github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/runtime/netpoll_epoll.go (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 package runtime 8 9 import "unsafe" 10 11 func epollcreate(size int32) int32 12 func epollcreate1(flags int32) int32 13 14 //go:noescape 15 func epollctl(epfd, op, fd int32, ev *epollevent) int32 16 17 //go:noescape 18 func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32 19 func closeonexec(fd int32) 20 21 var ( 22 epfd int32 = -1 // epoll descriptor 23 ) 24 25 func netpollinit() { 26 epfd = epollcreate1(_EPOLL_CLOEXEC) 27 if epfd >= 0 { 28 return 29 } 30 epfd = epollcreate(1024) 31 if epfd >= 0 { 32 closeonexec(epfd) 33 return 34 } 35 println("runtime: epollcreate failed with", -epfd) 36 throw("runtime: netpollinit failed") 37 } 38 39 func netpolldescriptor() uintptr { 40 return uintptr(epfd) 41 } 42 43 func netpollopen(fd uintptr, pd *pollDesc) int32 { 44 var ev epollevent 45 ev.events = _EPOLLIN | _EPOLLOUT | _EPOLLRDHUP | _EPOLLET 46 *(**pollDesc)(unsafe.Pointer(&ev.data)) = pd 47 return -epollctl(epfd, _EPOLL_CTL_ADD, int32(fd), &ev) 48 } 49 50 func netpollclose(fd uintptr) int32 { 51 var ev epollevent 52 return -epollctl(epfd, _EPOLL_CTL_DEL, int32(fd), &ev) 53 } 54 55 func netpollarm(pd *pollDesc, mode int) { 56 throw("runtime: unused") 57 } 58 59 // polls for ready network connections 60 // returns list of goroutines that become runnable 61 func netpoll(block bool) *g { 62 if epfd == -1 { 63 return nil 64 } 65 waitms := int32(-1) 66 if !block { 67 waitms = 0 68 } 69 var events [128]epollevent 70 retry: 71 n := epollwait(epfd, &events[0], int32(len(events)), waitms) 72 if n < 0 { 73 if n != -_EINTR { 74 println("runtime: epollwait on fd", epfd, "failed with", -n) 75 throw("runtime: netpoll failed") 76 } 77 goto retry 78 } 79 var gp guintptr 80 for i := int32(0); i < n; i++ { 81 ev := &events[i] 82 if ev.events == 0 { 83 continue 84 } 85 var mode int32 86 if ev.events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 { 87 mode += 'r' 88 } 89 if ev.events&(_EPOLLOUT|_EPOLLHUP|_EPOLLERR) != 0 { 90 mode += 'w' 91 } 92 if mode != 0 { 93 pd := *(**pollDesc)(unsafe.Pointer(&ev.data)) 94 95 netpollready(&gp, pd, mode) 96 } 97 } 98 if block && gp == 0 { 99 goto retry 100 } 101 return gp.ptr() 102 }