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)