parent
3efb5417dc
commit
40271cd1a7
40
grace.go
40
grace.go
@ -59,7 +59,6 @@ type Listener interface {
|
|||||||
// A goroutine based counter that provides graceful Close for listeners.
|
// A goroutine based counter that provides graceful Close for listeners.
|
||||||
type listener struct {
|
type listener struct {
|
||||||
FileListener
|
FileListener
|
||||||
closed bool // Indicates we're already closed.
|
|
||||||
closeRequest chan bool // Send a bool here to indicate we want to Close.
|
closeRequest chan bool // Send a bool here to indicate we want to Close.
|
||||||
allClosed chan bool // Receive from here will indicate a clean Close.
|
allClosed chan bool // Receive from here will indicate a clean Close.
|
||||||
counter chan bool // Use the inc/dec counters.
|
counter chan bool // Use the inc/dec counters.
|
||||||
@ -94,7 +93,7 @@ func (l *listener) enabler() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-l.closeRequest:
|
case <-l.closeRequest:
|
||||||
l.closed = true
|
l.closeRequest = nil
|
||||||
case change = <-l.counter:
|
case change = <-l.counter:
|
||||||
if change == inc {
|
if change == inc {
|
||||||
counter++
|
counter++
|
||||||
@ -102,19 +101,20 @@ func (l *listener) enabler() {
|
|||||||
counter--
|
counter--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if l.closed && counter == 0 {
|
if l.closeRequest == nil && counter == 0 {
|
||||||
l.allClosed <- true
|
close(l.allClosed)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *listener) CloseRequest() {
|
func (l *listener) CloseRequest() {
|
||||||
if l.closed == true {
|
select {
|
||||||
|
case l.closeRequest <- true:
|
||||||
|
<-l.allClosed
|
||||||
|
case <-l.allClosed:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.closeRequest <- true
|
|
||||||
<-l.allClosed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *listener) Close() error {
|
func (l *listener) Close() error {
|
||||||
@ -123,21 +123,23 @@ func (l *listener) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *listener) Accept() (net.Conn, error) {
|
func (l *listener) Accept() (net.Conn, error) {
|
||||||
if l.closed == true {
|
select {
|
||||||
|
case <-l.allClosed:
|
||||||
return nil, ErrAlreadyClosed
|
return nil, ErrAlreadyClosed
|
||||||
}
|
default:
|
||||||
c, err := l.FileListener.Accept()
|
c, err := l.FileListener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.HasSuffix(err.Error(), errClosed) {
|
if strings.HasSuffix(err.Error(), errClosed) {
|
||||||
return nil, ErrAlreadyClosed
|
return nil, ErrAlreadyClosed
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return nil, err
|
l.counter <- inc
|
||||||
|
return conn{
|
||||||
|
Conn: c,
|
||||||
|
counter: l.counter,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
l.counter <- inc
|
|
||||||
return conn{
|
|
||||||
Conn: c,
|
|
||||||
counter: l.counter,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for signals to gracefully terminate or restart the process.
|
// Wait for signals to gracefully terminate or restart the process.
|
||||||
|
Loading…
Reference in New Issue
Block a user