1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build darwin dragonfly freebsd netbsd openbsd
9 // Integrated network poller (kqueue-based implementation).
18 func kevent(kq
int32, ch
*keventt
, nch
uintptr, ev
*keventt
, nev
uintptr, ts
*timespec
) int32
20 //extern __go_fcntl_uintptr
21 func fcntlUintptr(fd
, cmd
, arg
uintptr) (uintptr, uintptr)
23 func closeonexec(fd
int32) {
24 fcntlUintptr(uintptr(fd
), _F_SETFD
, _FD_CLOEXEC
)
34 println("netpollinit: kqueue failed with", errno())
35 throw("runtime: netpollinit failed")
40 func netpolldescriptor() uintptr {
44 func netpollopen(fd
uintptr, pd
*pollDesc
) int32 {
45 // Arm both EVFILT_READ and EVFILT_WRITE in edge-triggered mode (EV_CLEAR)
46 // for the whole fd lifetime. The notifications are automatically unregistered
49 *(*uintptr)(unsafe
.Pointer(&ev
[0].ident
)) = fd
50 ev
[0].filter
= _EVFILT_READ
51 ev
[0].flags
= _EV_ADD | _EV_CLEAR
54 ev
[0].udata
= (*byte)(unsafe
.Pointer(pd
))
56 ev
[1].filter
= _EVFILT_WRITE
57 n
:= kevent(kq
, &ev
[0], 2, nil, 0, nil)
64 func netpollclose(fd
uintptr) int32 {
65 // Don't need to unregister because calling close()
66 // on fd will remove any kevents that reference the descriptor.
70 func netpollarm(pd
*pollDesc
, mode
int) {
71 throw("runtime: unused")
74 // Polls for ready network connections.
75 // Returns list of goroutines that become runnable.
76 func netpoll(block
bool) *g
{
85 var events
[64]keventt
87 n
:= kevent(kq
, nil, 0, &events
[0], uintptr(len(events
)), tp
)
91 println("runtime: kevent on fd", kq
, "failed with", e
)
92 throw("runtime: netpoll failed")
97 for i
:= 0; i
< int(n
); i
++ {
100 if ev
.filter
== _EVFILT_READ
{
103 if ev
.filter
== _EVFILT_WRITE
{
107 netpollready(&gp
, (*pollDesc
)(unsafe
.Pointer(ev
.udata
)), mode
)
110 if block
&& gp
== 0 {