added a stop request guard in starting a control channel

This commit is contained in:
hyung-hwan 2024-12-09 17:23:26 +09:00
parent f1c146d94f
commit 464a550c68
2 changed files with 44 additions and 17 deletions

View File

@ -1268,20 +1268,38 @@ func (c *Client) RunCtlTask(wg *sync.WaitGroup) {
// by creating the listener explicitly. // by creating the listener explicitly.
// err = cs.ListenAndServe() // err = cs.ListenAndServe()
// err = cs.ListenAndServeTLS("", "") // c.tlscfg must provide a certificate and a key // err = cs.ListenAndServeTLS("", "") // c.tlscfg must provide a certificate and a key
//cs.shuttingDown(), as the name indicates, is not expoosed by the net/http
//so I have to use my own indicator to check if it's been shutdown..
//
if c.stop_req.Load() == false {
// this guard has a flaw in that the stop request can be made
// between the check above and net.Listen() below.
l, err = net.Listen(tcp_addr_str_class(cs.Addr), cs.Addr) l, err = net.Listen(tcp_addr_str_class(cs.Addr), cs.Addr)
if err == nil { if err == nil {
if c.stop_req.Load() == false {
// check it again to make the guard slightly more stable
// although it's still possible that the stop request is made
// after Listen()
if c.ctltlscfg == nil { if c.ctltlscfg == nil {
err = cs.Serve(l) err = cs.Serve(l)
} else { } else {
err = cs.ServeTLS(l, "", "") // c.ctltlscfg must provide a certificate and a key err = cs.ServeTLS(l, "", "") // c.ctltlscfg must provide a certificate and a key
} }
} else {
err = fmt.Errorf("stop requested")
}
l.Close() l.Close()
} }
} else {
err = fmt.Errorf("stop requested")
}
if errors.Is(err, http.ErrServerClosed) { if errors.Is(err, http.ErrServerClosed) {
c.log.Write("", LOG_INFO, "Control channel[%d] ended", i) c.log.Write("", LOG_INFO, "Control channel[%d] ended", i)
} else { } else {
c.log.Write("", LOG_ERROR, "Control channel[%d] error - %s", i, err.Error()) c.log.Write("", LOG_ERROR, "Control channel[%d] error - %s", i, err.Error())
} }
l_wg.Done() l_wg.Done()
}(idx, ctl) }(idx, ctl)
} }

View File

@ -1020,18 +1020,27 @@ func (s *Server) RunCtlTask(wg *sync.WaitGroup) {
s.log.Write("", LOG_INFO, "Control channel[%d] started on %s", i, s.ctl_addr[i]) s.log.Write("", LOG_INFO, "Control channel[%d] started on %s", i, s.ctl_addr[i])
if s.stop_req.Load() == false {
// defeat hard-coded "tcp" in ListenAndServe() and ListenAndServeTLS() // defeat hard-coded "tcp" in ListenAndServe() and ListenAndServeTLS()
// err = cs.ListenAndServe() // err = cs.ListenAndServe()
// err = cs.ListenAndServeTLS("", "") // err = cs.ListenAndServeTLS("", "")
l, err = net.Listen(tcp_addr_str_class(cs.Addr), cs.Addr) l, err = net.Listen(tcp_addr_str_class(cs.Addr), cs.Addr)
if err == nil { if err == nil {
if s.stop_req.Load() == false {
if s.ctltlscfg == nil { if s.ctltlscfg == nil {
err = cs.Serve(l) err = cs.Serve(l)
} else { } else {
err = cs.ServeTLS(l, "", "") // s.ctltlscfg must provide a certificate and a key err = cs.ServeTLS(l, "", "") // s.ctltlscfg must provide a certificate and a key
} }
} else {
err = fmt.Errorf("stop requested")
}
l.Close() l.Close()
} }
} else {
err = fmt.Errorf("stop requested")
}
if errors.Is(err, http.ErrServerClosed) { if errors.Is(err, http.ErrServerClosed) {
s.log.Write("", LOG_INFO, "Control channel[%d] ended", i) s.log.Write("", LOG_INFO, "Control channel[%d] ended", i)
} else { } else {