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.
10 #include <sys/epoll.h>
17 #define EPOLLRDHUP 0x2000
21 #define EPOLL_CLOEXEC 02000000
24 #ifndef HAVE_EPOLL_CREATE1
25 extern int epoll_create1(int __flags
);
28 typedef struct epoll_event EpollEvent
;
31 runtime_epollcreate(int32 size
)
35 r
= epoll_create(size
);
42 runtime_epollcreate1(int32 flags
)
46 r
= epoll_create1(flags
);
53 runtime_epollctl(int32 epfd
, int32 op
, int32 fd
, EpollEvent
*ev
)
57 r
= epoll_ctl(epfd
, op
, fd
, ev
);
64 runtime_epollwait(int32 epfd
, EpollEvent
*ev
, int32 nev
, int32 timeout
)
68 r
= epoll_wait(epfd
, ev
, nev
, timeout
);
75 runtime_closeonexec(int32 fd
)
77 fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
80 static int32 epfd
= -1; // epoll descriptor
83 runtime_netpollinit(void)
85 epfd
= runtime_epollcreate1(EPOLL_CLOEXEC
);
88 epfd
= runtime_epollcreate(1024);
90 runtime_closeonexec(epfd
);
93 runtime_printf("netpollinit: failed to create descriptor (%d)\n", -epfd
);
94 runtime_throw("netpollinit: failed to create descriptor");
98 runtime_netpollopen(uintptr fd
, PollDesc
*pd
)
103 ev
.events
= EPOLLIN
|EPOLLOUT
|EPOLLRDHUP
|EPOLLET
;
104 ev
.data
.ptr
= (void*)pd
;
105 res
= runtime_epollctl(epfd
, EPOLL_CTL_ADD
, (int32
)fd
, &ev
);
110 runtime_netpollclose(uintptr fd
)
115 res
= runtime_epollctl(epfd
, EPOLL_CTL_DEL
, (int32
)fd
, &ev
);
119 // polls for ready network connections
120 // returns list of goroutines that become runnable
122 runtime_netpoll(bool block
)
124 static int32 lasterr
;
125 EpollEvent events
[128], *ev
;
126 int32 n
, i
, waitms
, mode
;
135 n
= runtime_epollwait(epfd
, events
, nelem(events
), waitms
);
137 if(n
!= -EINTR
&& n
!= lasterr
) {
139 runtime_printf("runtime: epollwait on fd %d failed with %d\n", epfd
, -n
);
144 for(i
= 0; i
< n
; i
++) {
149 if(ev
->events
& (EPOLLIN
|EPOLLRDHUP
|EPOLLHUP
|EPOLLERR
))
151 if(ev
->events
& (EPOLLOUT
|EPOLLHUP
|EPOLLERR
))
154 runtime_netpollready(&gp
, (void*)ev
->data
.ptr
, mode
);
156 if(block
&& gp
== nil
)
162 runtime_netpoll_scan(void (*addroot
)(Obj
))