-
Notifications
You must be signed in to change notification settings - Fork 3
/
fd_go19_unix.go
101 lines (83 loc) · 2.11 KB
/
fd_go19_unix.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// +build go1.9
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
package gotfo
import "syscall"
import "net"
type pollFD struct {
// Lock sysfd and serialize access to Read and Write methods.
fdmu fdMutex
// System file descriptor. Immutable until Close.
sysfd int
// I/O poller.
pd pollDesc
// Writev cache.
iovecs *[]syscall.Iovec
// Whether this is a streaming descriptor, as opposed to a
// packet-based descriptor like a UDP socket. Immutable.
IsStream bool
// Whether a zero byte read indicates EOF. This is false for a
// message based socket connection.
ZeroReadIsEOF bool
// Whether this is a file rather than a network socket.
isFile bool
}
// Network file descriptor.
type netFD struct {
pollFD
// immutable until Close
family int
sotype int
isConnected bool
net string
laddr net.Addr
raddr net.Addr
}
func newFD(fd int) *netFD {
nfd := &netFD{
pollFD: pollFD{
sysfd: fd,
IsStream: true,
ZeroReadIsEOF: true,
},
family: syscall.AF_INET,
sotype: syscall.SOCK_STREAM,
net: "tcp4",
}
return nfd
}
func (fd *netFD) init() error {
return fd.pd.init(fd)
}
func (fd *pollFD) incref() error {
if !fd.fdmu.incref() {
return errClosing
}
return nil
}
// decref removes a reference from fd.
// It also closes fd when the state of fd is set to closed and there
// is no remaining reference.
func (fd *pollFD) decref() error {
if fd.fdmu.decref() {
return fd.destroy()
}
return nil
}
// Destroy closes the file descriptor. This is called when there are
// no remaining references.
func (fd *pollFD) destroy() error {
// Poller may want to unregister fd in readiness notification mechanism,
// so this must be executed before CloseFunc.
fd.pd.close()
err := syscall.Close(fd.sysfd)
fd.sysfd = -1
return err
}
// Shutdown wraps the shutdown network call.
func (fd *pollFD) Shutdown(how int) error {
if err := fd.incref(); err != nil {
return err
}
defer fd.decref()
return syscall.Shutdown(fd.sysfd, how)
}