github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/runtime/netpoll_epoll.c (about) 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. 4 5 // +build linux 6 7 #include "runtime.h" 8 #include "defs_GOOS_GOARCH.h" 9 10 int32 runtime·epollcreate(int32 size); 11 int32 runtime·epollcreate1(int32 flags); 12 int32 runtime·epollctl(int32 epfd, int32 op, int32 fd, EpollEvent *ev); 13 int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 14 void runtime·closeonexec(int32 fd); 15 16 static int32 epfd = -1; // epoll descriptor 17 18 void 19 runtime·netpollinit(void) 20 { 21 epfd = runtime·epollcreate1(EPOLL_CLOEXEC); 22 if(epfd >= 0) 23 return; 24 epfd = runtime·epollcreate(1024); 25 if(epfd >= 0) { 26 runtime·closeonexec(epfd); 27 return; 28 } 29 runtime·printf("netpollinit: failed to create descriptor (%d)\n", -epfd); 30 runtime·throw("netpollinit: failed to create descriptor"); 31 } 32 33 int32 34 runtime·netpollopen(uintptr fd, PollDesc *pd) 35 { 36 EpollEvent ev; 37 int32 res; 38 39 ev.events = EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET; 40 ev.data = (uint64)pd; 41 res = runtime·epollctl(epfd, EPOLL_CTL_ADD, (int32)fd, &ev); 42 return -res; 43 } 44 45 int32 46 runtime·netpollclose(uintptr fd) 47 { 48 EpollEvent ev; 49 int32 res; 50 51 res = runtime·epollctl(epfd, EPOLL_CTL_DEL, (int32)fd, &ev); 52 return -res; 53 } 54 55 // polls for ready network connections 56 // returns list of goroutines that become runnable 57 G* 58 runtime·netpoll(bool block) 59 { 60 static int32 lasterr; 61 EpollEvent events[128], *ev; 62 int32 n, i, waitms, mode; 63 G *gp; 64 65 if(epfd == -1) 66 return nil; 67 waitms = -1; 68 if(!block) 69 waitms = 0; 70 retry: 71 n = runtime·epollwait(epfd, events, nelem(events), waitms); 72 if(n < 0) { 73 if(n != -EINTR && n != lasterr) { 74 lasterr = n; 75 runtime·printf("runtime: epollwait on fd %d failed with %d\n", epfd, -n); 76 } 77 goto retry; 78 } 79 gp = nil; 80 for(i = 0; i < n; i++) { 81 ev = &events[i]; 82 if(ev->events == 0) 83 continue; 84 mode = 0; 85 if(ev->events & (EPOLLIN|EPOLLRDHUP|EPOLLHUP|EPOLLERR)) 86 mode += 'r'; 87 if(ev->events & (EPOLLOUT|EPOLLHUP|EPOLLERR)) 88 mode += 'w'; 89 if(mode) 90 runtime·netpollready(&gp, (void*)ev->data, mode); 91 } 92 if(block && gp == nil) 93 goto retry; 94 return gp; 95 }