github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/poller/netpoll/handle.go (about) 1 package netpoll 2 3 import ( 4 "net" 5 "os" 6 ) 7 8 // filer describes an object that has ability to return os.File. 9 type filer interface { 10 // File returns a copy of object's file descriptor. 11 File() (*os.File, error) 12 } 13 14 // Desc is a network connection within netpoll descriptor. 15 // It's methods are not goroutine safe. 16 type Desc struct { 17 file *os.File 18 event Event 19 } 20 21 // NewDesc creates descriptor from custom fd. 22 func NewDesc(fd uintptr, ev Event) *Desc { 23 return &Desc{os.NewFile(fd, ""), ev} 24 } 25 26 // Close closes underlying file. 27 func (h *Desc) Close() error { 28 return h.file.Close() 29 } 30 31 func (h *Desc) fd() int { 32 return int(h.file.Fd()) 33 } 34 35 // Must is a helper that wraps a call to a function returning (*Desc, error). 36 // It panics if the error is non-nil and returns desc if not. 37 // It is intended for use in short Desc initializations. 38 func Must(desc *Desc, err error) *Desc { 39 if err != nil { 40 panic(err) 41 } 42 return desc 43 } 44 45 // HandleRead creates read descriptor for further use in Poller methods. 46 // It is the same as Handle(conn, EventRead|EventEdgeTriggered). 47 func HandleRead(conn net.Conn) (*Desc, error) { 48 return Handle(conn, EventRead|EventEdgeTriggered) 49 } 50 51 // HandleReadOnce creates read descriptor for further use in Poller methods. 52 // It is the same as Handle(conn, EventRead|EventOneShot). 53 func HandleReadOnce(conn net.Conn) (*Desc, error) { 54 return Handle(conn, EventRead|EventOneShot) 55 } 56 57 // HandleWrite creates write descriptor for further use in Poller methods. 58 // It is the same as Handle(conn, EventWrite|EventEdgeTriggered). 59 func HandleWrite(conn net.Conn) (*Desc, error) { 60 return Handle(conn, EventWrite|EventEdgeTriggered) 61 } 62 63 // HandleWriteOnce creates write descriptor for further use in Poller methods. 64 // It is the same as Handle(conn, EventWrite|EventOneShot). 65 func HandleWriteOnce(conn net.Conn) (*Desc, error) { 66 return Handle(conn, EventWrite|EventOneShot) 67 } 68 69 // HandleReadWrite creates read and write descriptor for further use in Poller 70 // methods. 71 // It is the same as Handle(conn, EventRead|EventWrite|EventEdgeTriggered). 72 func HandleReadWrite(conn net.Conn) (*Desc, error) { 73 return Handle(conn, EventRead|EventWrite|EventEdgeTriggered) 74 } 75 76 // Handle creates new Desc with given conn and event. 77 // Returned descriptor could be used as argument to Start(), Resume() and 78 // Stop() methods of some Poller implementation. 79 func Handle(conn net.Conn, event Event) (*Desc, error) { 80 desc, err := handle(conn, event) 81 if err != nil { 82 return nil, err 83 } 84 85 // Set the file back to non blocking mode since conn.File() sets underlying 86 // os.File to blocking mode. This is useful to get conn.Set{Read}Deadline 87 // methods still working on source Conn. 88 // 89 // See https://golang.org/pkg/net/#TCPConn.File 90 // See /usr/local/go/src/net/net.go: conn.File() 91 if err = setNonblock(desc.fd(), true); err != nil { 92 return nil, os.NewSyscallError("setnonblock", err) 93 } 94 95 return desc, nil 96 } 97 98 // HandleListener returns descriptor for a net.Listener. 99 func HandleListener(ln net.Listener, event Event) (*Desc, error) { 100 return handle(ln, event) 101 } 102 103 func handle(x interface{}, event Event) (*Desc, error) { 104 f, ok := x.(filer) 105 if !ok { 106 return nil, ErrNotFiler 107 } 108 109 // Get a copy of fd. 110 file, err := f.File() 111 if err != nil { 112 return nil, err 113 } 114 115 return &Desc{ 116 file: file, 117 event: event, 118 }, nil 119 }