* DHCP: Stop(): wait until the worker is stopped
This commit is contained in:
parent
6f69fb73af
commit
b5f0d48e7f
@ -40,6 +40,11 @@ type Server struct {
|
|||||||
|
|
||||||
ipnet *net.IPNet // if interface name changes, this needs to be reset
|
ipnet *net.IPNet // if interface name changes, this needs to be reset
|
||||||
|
|
||||||
|
cond *sync.Cond // Synchronize worker thread with main thread
|
||||||
|
mutex sync.Mutex // Mutex for 'cond'
|
||||||
|
running bool // Set if the worker thread is running
|
||||||
|
stopping bool // Set if the worker thread should be stopped
|
||||||
|
|
||||||
// leases
|
// leases
|
||||||
leases []*Lease
|
leases []*Lease
|
||||||
leaseStart net.IP // parsed from config RangeStart
|
leaseStart net.IP // parsed from config RangeStart
|
||||||
@ -131,14 +136,18 @@ func (s *Server) Start(config *ServerConfig) error {
|
|||||||
log.Info("DHCP: listening on 0.0.0.0:67")
|
log.Info("DHCP: listening on 0.0.0.0:67")
|
||||||
|
|
||||||
s.conn = c
|
s.conn = c
|
||||||
|
s.cond = sync.NewCond(&s.mutex)
|
||||||
|
|
||||||
|
s.running = true
|
||||||
go func() {
|
go func() {
|
||||||
// operate on c instead of c.conn because c.conn can change over time
|
// operate on c instead of c.conn because c.conn can change over time
|
||||||
err := dhcp4.Serve(c, s)
|
err := dhcp4.Serve(c, s)
|
||||||
if err != nil {
|
if err != nil && !s.stopping {
|
||||||
log.Printf("dhcp4.Serve() returned with error: %s", err)
|
log.Printf("dhcp4.Serve() returned with error: %s", err)
|
||||||
}
|
}
|
||||||
c.Close() // in case Serve() exits for other reason than listening socket closure
|
c.Close() // in case Serve() exits for other reason than listening socket closure
|
||||||
|
s.running = false
|
||||||
|
s.cond.Signal()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -150,11 +159,22 @@ func (s *Server) Stop() error {
|
|||||||
// nothing to do, return silently
|
// nothing to do, return silently
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.stopping = true
|
||||||
|
|
||||||
err := s.closeConn()
|
err := s.closeConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapErrPrint(err, "Couldn't close UDP listening socket")
|
return wrapErrPrint(err, "Couldn't close UDP listening socket")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We've just closed the listening socket.
|
||||||
|
// Worker thread should exit right after it tries to read from the socket.
|
||||||
|
s.mutex.Lock()
|
||||||
|
for s.running {
|
||||||
|
s.cond.Wait()
|
||||||
|
}
|
||||||
|
s.mutex.Unlock()
|
||||||
|
|
||||||
s.dbStore()
|
s.dbStore()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user