...
Run Format

Source file src/runtime/netpoll_epoll.go

     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("netpollinit: failed to create epoll descriptor", -epfd)
    36		throw("netpollinit: failed to create descriptor")
    37	}
    38	
    39	func netpollopen(fd uintptr, pd *pollDesc) int32 {
    40		var ev epollevent
    41		ev.events = _EPOLLIN | _EPOLLOUT | _EPOLLRDHUP | _EPOLLET
    42		*(**pollDesc)(unsafe.Pointer(&ev.data)) = pd
    43		return -epollctl(epfd, _EPOLL_CTL_ADD, int32(fd), &ev)
    44	}
    45	
    46	func netpollclose(fd uintptr) int32 {
    47		var ev epollevent
    48		return -epollctl(epfd, _EPOLL_CTL_DEL, int32(fd), &ev)
    49	}
    50	
    51	func netpollarm(pd *pollDesc, mode int) {
    52		throw("unused")
    53	}
    54	
    55	// polls for ready network connections
    56	// returns list of goroutines that become runnable
    57	func netpoll(block bool) *g {
    58		if epfd == -1 {
    59			return nil
    60		}
    61		waitms := int32(-1)
    62		if !block {
    63			waitms = 0
    64		}
    65		var events [128]epollevent
    66	retry:
    67		n := epollwait(epfd, &events[0], int32(len(events)), waitms)
    68		if n < 0 {
    69			if n != -_EINTR {
    70				println("runtime: epollwait on fd", epfd, "failed with", -n)
    71				throw("epollwait failed")
    72			}
    73			goto retry
    74		}
    75		var gp guintptr
    76		for i := int32(0); i < n; i++ {
    77			ev := &events[i]
    78			if ev.events == 0 {
    79				continue
    80			}
    81			var mode int32
    82			if ev.events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 {
    83				mode += 'r'
    84			}
    85			if ev.events&(_EPOLLOUT|_EPOLLHUP|_EPOLLERR) != 0 {
    86				mode += 'w'
    87			}
    88			if mode != 0 {
    89				pd := *(**pollDesc)(unsafe.Pointer(&ev.data))
    90	
    91				netpollready(&gp, pd, mode)
    92			}
    93		}
    94		if block && gp == 0 {
    95			goto retry
    96		}
    97		return gp.ptr()
    98	}
    99	

View as plain text