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("netpollinit: kqueue failed")
40 func netpollopen(fd
uintptr, pd
*pollDesc
) int32 {
41 // Arm both EVFILT_READ and EVFILT_WRITE in edge-triggered mode (EV_CLEAR)
42 // for the whole fd lifetime. The notifications are automatically unregistered
45 *(*uintptr)(unsafe
.Pointer(&ev
[0].ident
)) = fd
46 ev
[0].filter
= _EVFILT_READ
47 ev
[0].flags
= _EV_ADD | _EV_CLEAR
50 ev
[0].udata
= (*byte)(unsafe
.Pointer(pd
))
52 ev
[1].filter
= _EVFILT_WRITE
53 n
:= kevent(kq
, &ev
[0], 2, nil, 0, nil)
60 func netpollclose(fd
uintptr) int32 {
61 // Don't need to unregister because calling close()
62 // on fd will remove any kevents that reference the descriptor.
66 func netpollarm(pd
*pollDesc
, mode
int) {
70 // Polls for ready network connections.
71 // Returns list of goroutines that become runnable.
72 func netpoll(block
bool) *g
{
81 var events
[64]keventt
83 n
:= kevent(kq
, nil, 0, &events
[0], uintptr(len(events
)), tp
)
87 println("runtime: kevent on fd", kq
, "failed with", e
)
88 throw("kevent failed")
93 for i
:= 0; i
< int(n
); i
++ {
96 if ev
.filter
== _EVFILT_READ
{
99 if ev
.filter
== _EVFILT_WRITE
{
103 netpollready(&gp
, (*pollDesc
)(unsafe
.Pointer(ev
.udata
)), mode
)
106 if block
&& gp
== 0 {