github.com/Uptycs/basequery-go@v0.8.0/transport/transport_windows.go (about) 1 package transport 2 3 import ( 4 "net" 5 "sync" 6 "time" 7 8 "github.com/Microsoft/go-winio" 9 "github.com/pkg/errors" 10 11 "github.com/apache/thrift/lib/go/thrift" 12 ) 13 14 // Open opens the named pipe with the provided path and timeout, 15 // returning a TTransport. 16 func Open(path string, timeout time.Duration) (*thrift.TSocket, error) { 17 conn, err := winio.DialPipe(path, &timeout) 18 if err != nil { 19 return nil, errors.Wrapf(err, "dialing pipe '%s'", path) 20 } 21 return thrift.NewTSocketFromConnTimeout(conn, timeout), nil 22 } 23 24 func OpenServer(pipePath string, timeout time.Duration) (*TServerPipe, error) { 25 return NewTServerPipeTimeout(pipePath, timeout) 26 } 27 28 // TServerPipe is a windows named pipe implementation of the 29 type TServerPipe struct { 30 listener net.Listener 31 pipePath string 32 clientTimeout time.Duration 33 34 // Protects the interrupted value to make it thread safe. 35 mu sync.RWMutex 36 interrupted bool 37 } 38 39 func NewTServerPipeTimeout(pipePath string, clientTimeout time.Duration) (*TServerPipe, error) { 40 return &TServerPipe{pipePath: pipePath, clientTimeout: clientTimeout}, nil 41 } 42 43 func (p *TServerPipe) Listen() error { 44 p.mu.Lock() 45 defer p.mu.Unlock() 46 47 if p.IsListening() { 48 return nil 49 } 50 51 l, err := winio.ListenPipe(p.pipePath, nil) 52 if err != nil { 53 return err 54 } 55 56 p.listener = l 57 return nil 58 } 59 60 // IsListening returns whether the server transport is currently listening. 61 func (p *TServerPipe) IsListening() bool { 62 return p.listener != nil 63 } 64 65 // Accept wraps the standard net.Listener accept to return a thrift.TTransport. 66 func (p *TServerPipe) Accept() (thrift.TTransport, error) { 67 p.mu.RLock() 68 interrupted := p.interrupted 69 listener := p.listener 70 p.mu.RUnlock() 71 72 if interrupted { 73 return nil, errors.New("transport interrupted") 74 } 75 76 conn, err := listener.Accept() 77 if err != nil { 78 return nil, thrift.NewTTransportExceptionFromError(err) 79 } 80 return thrift.NewTSocketFromConnTimeout(conn, p.clientTimeout), nil 81 } 82 83 func (p *TServerPipe) Close() error { 84 defer func() { 85 p.listener = nil 86 }() 87 if p.IsListening() { 88 return p.listener.Close() 89 } 90 return nil 91 } 92 93 // Interrupt is a noop for this implementation 94 func (p *TServerPipe) Interrupt() error { 95 p.mu.Lock() 96 defer p.mu.Unlock() 97 98 p.interrupted = true 99 p.Close() 100 101 return nil 102 }