import (
"net"
+ "sync"
"time"
)
listener net.Listener
addr net.Addr
clientTimeout time.Duration
- interrupted bool
+
+ // Protects the interrupted value to make it thread safe.
+ mu sync.RWMutex
+ interrupted bool
}
func NewTServerSocket(listenAddr string) (*TServerSocket, error) {
}
func (p *TServerSocket) Accept() (TTransport, error) {
- if p.interrupted {
+ p.mu.RLock()
+ interrupted := p.interrupted
+ p.mu.RUnlock()
+
+ if interrupted {
return nil, errTransportInterrupted
}
if p.listener == nil {
}
func (p *TServerSocket) Interrupt() error {
+ p.mu.Lock()
p.interrupted = true
+ p.mu.Unlock()
+
return nil
}
// Simple, non-concurrent server for testing.
type TSimpleServer struct {
- stopped bool
+ quit chan struct{}
processorFactory TProcessorFactory
serverTransport TServerTransport
}
func NewTSimpleServerFactory6(processorFactory TProcessorFactory, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer {
- return &TSimpleServer{processorFactory: processorFactory,
+ return &TSimpleServer{
+ processorFactory: processorFactory,
serverTransport: serverTransport,
inputTransportFactory: inputTransportFactory,
outputTransportFactory: outputTransportFactory,
inputProtocolFactory: inputProtocolFactory,
outputProtocolFactory: outputProtocolFactory,
+ quit: make(chan struct{}, 1),
}
}
}
func (p *TSimpleServer) Serve() error {
- p.stopped = false
err := p.serverTransport.Listen()
if err != nil {
return err
}
- for !p.stopped {
+
+loop:
+ for {
+ select {
+ case <-p.quit:
+ break loop
+ default:
+ }
+
client, err := p.serverTransport.Accept()
if err != nil {
log.Println("Accept err: ", err)
}
func (p *TSimpleServer) Stop() error {
- p.stopped = true
+ p.quit <- struct{}{}
p.serverTransport.Interrupt()
return nil
}