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>
16 #define EPOLLRDHUP 0x2000
20 #define EPOLL_CLOEXEC 02000000
23 #ifndef HAVE_EPOLL_CREATE1
24 extern int epoll_create1(int __flags
);
27 typedef struct epoll_event EpollEvent
;
30 runtime_epollcreate(int32 size
)
34 r
= epoll_create(size
);
41 runtime_epollcreate1(int32 flags
)
45 r
= epoll_create1(flags
);
52 runtime_epollctl(int32 epfd
, int32 op
, int32 fd
, EpollEvent
*ev
)
56 r
= epoll_ctl(epfd
, op
, fd
, ev
);
63 runtime_epollwait(int32 epfd
, EpollEvent
*ev
, int32 nev
, int32 timeout
)
67 r
= epoll_wait(epfd
, ev
, nev
, timeout
);
74 runtime_closeonexec(int32 fd
)
76 fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
79 static int32 epfd
= -1; // epoll descriptor
82 runtime_netpollinit(void)
84 epfd
= runtime_epollcreate1(EPOLL_CLOEXEC
);
87 epfd
= runtime_epollcreate(1024);
89 runtime_closeonexec(epfd
);
92 runtime_printf("netpollinit: failed to create descriptor (%d)\n", -epfd
);
93 runtime_throw("netpollinit: failed to create descriptor");
97 runtime_netpollopen(int32 fd
, PollDesc
*pd
)
102 ev
.events
= EPOLLIN
|EPOLLOUT
|EPOLLRDHUP
|EPOLLET
;
103 ev
.data
.ptr
= (void*)pd
;
104 res
= runtime_epollctl(epfd
, EPOLL_CTL_ADD
, fd
, &ev
);
109 runtime_netpollclose(int32 fd
)
114 res
= runtime_epollctl(epfd
, EPOLL_CTL_DEL
, fd
, &ev
);
118 // polls for ready network connections
119 // returns list of goroutines that become runnable
121 runtime_netpoll(bool block
)
123 static int32 lasterr
;
124 EpollEvent events
[128], *ev
;
125 int32 n
, i
, waitms
, mode
;
134 n
= runtime_epollwait(epfd
, events
, nelem(events
), waitms
);
136 if(n
!= -EINTR
&& n
!= lasterr
) {
138 runtime_printf("runtime: epollwait on fd %d failed with %d\n", epfd
, -n
);
143 for(i
= 0; i
< n
; i
++) {
148 if(ev
->events
& (EPOLLIN
|EPOLLRDHUP
|EPOLLHUP
|EPOLLERR
))
150 if(ev
->events
& (EPOLLOUT
|EPOLLHUP
|EPOLLERR
))
153 runtime_netpollready(&gp
, (void*)ev
->data
.ptr
, mode
);
155 if(block
&& gp
== nil
)