2017-03-02 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgo / go / runtime / netpoll_epoll.go
blob247692ef0422a48222f7eeb8d5ea45e636130479
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.
5 // +build linux
7 package runtime
9 import "unsafe"
11 //extern epoll_create
12 func epollcreate(size int32) int32
14 //extern epoll_create1
15 func epollcreate1(flags int32) int32
17 //go:noescape
18 //extern epoll_ctl
19 func epollctl(epfd, op, fd int32, ev *epollevent) int32
21 //go:noescape
22 //extern epoll_wait
23 func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32
25 //extern __go_fcntl_uintptr
26 func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr)
28 func closeonexec(fd int32) {
29 fcntlUintptr(uintptr(fd), _F_SETFD, _FD_CLOEXEC)
32 var (
33 epfd int32 = -1 // epoll descriptor
36 func netpollinit() {
37 epfd = epollcreate1(_EPOLL_CLOEXEC)
38 if epfd >= 0 {
39 return
41 epfd = epollcreate(1024)
42 if epfd >= 0 {
43 closeonexec(epfd)
44 return
46 println("netpollinit: failed to create epoll descriptor", errno())
47 throw("netpollinit: failed to create descriptor")
50 func netpollopen(fd uintptr, pd *pollDesc) int32 {
51 var ev epollevent
52 ev.events = _EPOLLIN | _EPOLLOUT | _EPOLLRDHUP | _EPOLLETpos
53 *(**pollDesc)(unsafe.Pointer(&ev.data)) = pd
54 if epollctl(epfd, _EPOLL_CTL_ADD, int32(fd), &ev) < 0 {
55 return int32(errno())
57 return 0
60 func netpollclose(fd uintptr) int32 {
61 var ev epollevent
62 if epollctl(epfd, _EPOLL_CTL_DEL, int32(fd), &ev) < 0 {
63 return int32(errno())
65 return 0
68 func netpollarm(pd *pollDesc, mode int) {
69 throw("unused")
72 // polls for ready network connections
73 // returns list of goroutines that become runnable
74 func netpoll(block bool) *g {
75 if epfd == -1 {
76 return nil
78 waitms := int32(-1)
79 if !block {
80 waitms = 0
82 var events [128]epollevent
83 retry:
84 n := epollwait(epfd, &events[0], int32(len(events)), waitms)
85 if n < 0 {
86 e := errno()
87 if e != _EINTR {
88 println("runtime: epollwait on fd", epfd, "failed with", e)
89 throw("epollwait failed")
91 goto retry
93 var gp guintptr
94 for i := int32(0); i < n; i++ {
95 ev := &events[i]
96 if ev.events == 0 {
97 continue
99 var mode int32
100 if ev.events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 {
101 mode += 'r'
103 if ev.events&(_EPOLLOUT|_EPOLLHUP|_EPOLLERR) != 0 {
104 mode += 'w'
106 if mode != 0 {
107 pd := *(**pollDesc)(unsafe.Pointer(&ev.data))
109 netpollready(&gp, pd, mode)
112 if block && gp == 0 {
113 goto retry
115 return gp.ptr()