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  }