Fix server freezing on Windows.

This commit is contained in:
Mikkel Krautz 2011-05-17 20:23:28 +02:00
parent 22febd0b13
commit fbf81bafe0
2 changed files with 39 additions and 1 deletions

View file

@ -13,6 +13,7 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"runtime"
) )
type frozenServer struct { type frozenServer struct {
@ -64,7 +65,7 @@ type frozenGroup struct {
Remove []int "remove" Remove []int "remove"
} }
// Freeze a server and write it to a file // Freeze a server and write it to a file.
func (server *Server) FreezeToFile(filename string) (err os.Error) { func (server *Server) FreezeToFile(filename string) (err os.Error) {
r := server.FreezeServer() r := server.FreezeServer()
if err != nil { if err != nil {
@ -90,6 +91,28 @@ func (server *Server) FreezeToFile(filename string) (err os.Error) {
if err != nil { if err != nil {
return err return err
} }
// Temporary non-atomic path
// We should probably use MoveFileEx instead, but I'm
// not sure whether that's atomic either. MoveFileTransacted
// would be prefered for Vista/Server 2008+.
if runtime.GOOS == "windows" {
err = os.Remove(filename + ".old")
if e, ok := err.(*os.PathError); ok {
if e.Error != os.ENOENT {
return err
}
} else if err != nil {
return err
}
err = os.Rename(filename, filename + ".old")
if e, ok := err.(*os.LinkError); ok {
if e.Error != os.ENOENT {
return err
}
} else if err != nil {
return err
}
}
err = os.Rename(f.Name(), filename) err = os.Rename(f.Name(), filename)
if err != nil { if err != nil {
return err return err

View file

@ -16,6 +16,7 @@ import (
"regexp" "regexp"
"rpc" "rpc"
"runtime" "runtime"
"strconv"
"time" "time"
) )
@ -206,6 +207,20 @@ func main() {
servers[s.Id] = s servers[s.Id] = s
go s.ListenAndMurmur() go s.ListenAndMurmur()
} }
// win32 special-case
if matched, _ := regexp.MatchString("^[0-9]+.old$", name); matched {
sid, _ := strconv.Atoi64(name[0:len(name)-4])
_, exists := servers[sid]
if !exists {
log.Printf("Recovering lost server %v", name)
s, err := NewServerFromFrozen(filepath.Join(*datadir, name))
if err != nil {
log.Fatalf("Unable to recover server: %S", err.String())
}
servers[sid] = s
go s.ListenAndMurmur()
}
}
} }
if len(servers) == 0 { if len(servers) == 0 {