Skip to content

Commit

Permalink
Merge pull request #92 from pin/shutdown-hook-race-fix
Browse files Browse the repository at this point in the history
Make Shutdown blocking to ensure outstanding requests completion
  • Loading branch information
pin authored Nov 12, 2023
2 parents 5fda30d + c06e820 commit 71d1b5e
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 8 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Set of features is sufficient for PXE boot support.
import "github.com/pin/tftp/v3"
```

The package is cohesive to Golang `io`. Particularly it implements
The package is cohesive to Golang `io` and implements
`io.ReaderFrom` and `io.WriterTo` interfaces. That allows efficient data
transmission without unnecessary memory copying and allocations.

Expand Down Expand Up @@ -71,6 +71,8 @@ func main() {
}
```

See [gotftpd](https://github.com/pin/golang-tftp-example/blob/master/src/gotftpd/main.go) in [golang-tftp-example](https://github.com/pin/golang-tftp-example) repository for working code.

TFTP Client
-----------
Upload file to server:
Expand Down Expand Up @@ -98,7 +100,7 @@ n, err := wt.WriteTo(file)
fmt.Printf("%d bytes received\n", n)
```

Note: please handle errors better :)
See [goftp](https://github.com/pin/golang-tftp-example/blob/master/src/gotftp/main.go) in [golang-tftp-example](https://github.com/pin/golang-tftp-example) repository for working code.

TSize option
------------
Expand Down
17 changes: 12 additions & 5 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,8 @@ func (s *Server) ListenAndServe(addr string) error {
// Serve starts server provided already opened UDP connection. It is
// useful for the case when you want to run server in separate goroutine
// but still want to be able to handle any errors opening connection.
// Serve returns when Shutdown is called or connection is closed.
// Serve returns when Shutdown is called.
func (s *Server) Serve(conn net.PacketConn) error {
// defer conn.Close()
laddr := conn.LocalAddr()
host, _, err := net.SplitHostPort(laddr.String())
if err != nil {
Expand Down Expand Up @@ -232,7 +231,7 @@ func (s *Server) Serve(conn net.PacketConn) error {
for {
select {
case <-s.cancel.Done():
s.wg.Wait()
// Stop server because Shutdown was called
return nil
default:
var err error
Expand All @@ -250,7 +249,6 @@ func (s *Server) Serve(conn net.PacketConn) error {
}
}
}
return nil
}

// Yes, I don't really like having separate IPv4 and IPv6 variants,
Expand Down Expand Up @@ -309,13 +307,22 @@ func (s *Server) processRequest() error {

// Shutdown make server stop listening for new requests, allows
// server to finish outstanding transfers and stops server.
// Shutdown blocks until all outstanding requests are processed or timed out.
// Calling Shutdown from the handler or hook might cause deadlock.
func (s *Server) Shutdown() {
if !s.singlePort {
s.Lock()
s.conn.Close()
// Connection could not exist if Serve or
// ListenAndServe was never called.
if s.conn != nil {
s.conn.Close()
}
s.Unlock()
}
s.cancelFn()
if !s.singlePort {
s.wg.Wait()
}
}

func (s *Server) handlePacket(localAddr net.IP, remoteAddr *net.UDPAddr, buffer []byte, n, maxBlockLen int, listener chan []byte) error {
Expand Down
2 changes: 1 addition & 1 deletion tftp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func TestPackUnpack(t *testing.T) {
v := []string{"test-filename/with-subdir"}
testOptsList := []options{
nil,
options{
{
"tsize": "1234",
"blksize": "22",
},
Expand Down

0 comments on commit 71d1b5e

Please sign in to comment.