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).
16 func kevent(kq
int32, ch
*keventt
, nch
int32, ev
*keventt
, nev
int32, ts
*timespec
) int32
17 func closeonexec(fd
int32)
27 println("netpollinit: kqueue failed with", -kq
)
28 gothrow("netpollinit: kqueue failed")
33 func netpollopen(fd
uintptr, pd
*pollDesc
) int32 {
34 // Arm both EVFILT_READ and EVFILT_WRITE in edge-triggered mode (EV_CLEAR)
35 // for the whole fd lifetime. The notifications are automatically unregistered
38 *(*uintptr)(unsafe
.Pointer(&ev
[0].ident
)) = fd
39 ev
[0].filter
= _EVFILT_READ
40 ev
[0].flags
= _EV_ADD | _EV_CLEAR
43 ev
[0].udata
= (*byte)(unsafe
.Pointer(pd
))
45 ev
[1].filter
= _EVFILT_WRITE
46 n
:= kevent(kq
, &ev
[0], 2, nil, 0, nil)
53 func netpollclose(fd
uintptr) int32 {
54 // Don't need to unregister because calling close()
55 // on fd will remove any kevents that reference the descriptor.
59 func netpollarm(pd
*pollDesc
, mode
int) {
63 // Polls for ready network connections.
64 // Returns list of goroutines that become runnable.
65 func netpoll(block
bool) (gp
*g
) {
74 var events
[64]keventt
76 n
:= kevent(kq
, nil, 0, &events
[0], int32(len(events
)), tp
)
78 if n
!= -_EINTR
&& n
!= netpolllasterr
{
80 println("runtime: kevent on fd", kq
, "failed with", -n
)
84 for i
:= 0; i
< int(n
); i
++ {
87 if ev
.filter
== _EVFILT_READ
{
90 if ev
.filter
== _EVFILT_WRITE
{
94 netpollready((**g
)(noescape(unsafe
.Pointer(&gp
))), (*pollDesc
)(unsafe
.Pointer(ev
.udata
)), mode
)
97 if block
&& gp
== nil {