@@ -13,11 +13,9 @@ import (
13
13
)
14
14
15
15
var (
16
- epfd int32 = - 1 // epoll descriptor
17
-
18
- netpollBreakRd , netpollBreakWr uintptr // for netpollBreak
19
-
20
- netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
16
+ epfd int32 = - 1 // epoll descriptor
17
+ netpollEventFd uintptr // eventfd for netpollBreak
18
+ netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
21
19
)
22
20
23
21
func netpollinit () {
@@ -27,26 +25,25 @@ func netpollinit() {
27
25
println ("runtime: epollcreate failed with" , errno )
28
26
throw ("runtime: netpollinit failed" )
29
27
}
30
- r , w , errpipe := nonblockingPipe ( )
31
- if errpipe != 0 {
32
- println ("runtime: pipe failed with" , - errpipe )
33
- throw ("runtime: pipe failed" )
28
+ efd , errno := syscall . Eventfd ( 0 , syscall . EFD_CLOEXEC | syscall . EFD_NONBLOCK )
29
+ if errno != 0 {
30
+ println ("runtime: eventfd failed with" , - errno )
31
+ throw ("runtime: eventfd failed" )
34
32
}
35
33
ev := syscall.EpollEvent {
36
34
Events : syscall .EPOLLIN ,
37
35
}
38
- * (* * uintptr )(unsafe .Pointer (& ev .Data )) = & netpollBreakRd
39
- errno = syscall .EpollCtl (epfd , syscall .EPOLL_CTL_ADD , r , & ev )
36
+ * (* * uintptr )(unsafe .Pointer (& ev .Data )) = & netpollEventFd
37
+ errno = syscall .EpollCtl (epfd , syscall .EPOLL_CTL_ADD , efd , & ev )
40
38
if errno != 0 {
41
39
println ("runtime: epollctl failed with" , errno )
42
40
throw ("runtime: epollctl failed" )
43
41
}
44
- netpollBreakRd = uintptr (r )
45
- netpollBreakWr = uintptr (w )
42
+ netpollEventFd = uintptr (efd )
46
43
}
47
44
48
45
func netpollIsPollDescriptor (fd uintptr ) bool {
49
- return fd == uintptr (epfd ) || fd == netpollBreakRd || fd == netpollBreakWr
46
+ return fd == uintptr (epfd ) || fd == netpollEventFd
50
47
}
51
48
52
49
func netpollopen (fd uintptr , pd * pollDesc ) uintptr {
@@ -73,10 +70,11 @@ func netpollBreak() {
73
70
return
74
71
}
75
72
73
+ var one uint64 = 1
74
+ oneSize := int32 (unsafe .Sizeof (one ))
76
75
for {
77
- var b byte
78
- n := write (netpollBreakWr , unsafe .Pointer (& b ), 1 )
79
- if n == 1 {
76
+ n := write (netpollEventFd , noescape (unsafe .Pointer (& one )), oneSize )
77
+ if n == oneSize {
80
78
break
81
79
}
82
80
if n == - _EINTR {
@@ -136,17 +134,19 @@ retry:
136
134
continue
137
135
}
138
136
139
- if * (* * uintptr )(unsafe .Pointer (& ev .Data )) == & netpollBreakRd {
137
+ if * (* * uintptr )(unsafe .Pointer (& ev .Data )) == & netpollEventFd {
140
138
if ev .Events != syscall .EPOLLIN {
141
- println ("runtime: netpoll: break fd ready for" , ev .Events )
142
- throw ("runtime: netpoll: break fd ready for something unexpected" )
139
+ println ("runtime: netpoll: eventfd ready for" , ev .Events )
140
+ throw ("runtime: netpoll: eventfd ready for something unexpected" )
143
141
}
144
142
if delay != 0 {
145
143
// netpollBreak could be picked up by a
146
- // nonblocking poll. Only read the byte
147
- // if blocking.
148
- var tmp [16 ]byte
149
- read (int32 (netpollBreakRd ), noescape (unsafe .Pointer (& tmp [0 ])), int32 (len (tmp )))
144
+ // nonblocking poll. Only read the 8-byte
145
+ // integer if blocking.
146
+ // Since EFD_SEMAPHORE was not specified,
147
+ // the eventfd counter will be reset to 0.
148
+ var one uint64
149
+ read (int32 (netpollEventFd ), noescape (unsafe .Pointer (& one )), int32 (unsafe .Sizeof (one )))
150
150
netpollWakeSig .Store (0 )
151
151
}
152
152
continue
0 commit comments