- Code Path:
src/runtime/netpoll.go
Network polling is platform-dependent, the following is of BSD family operating systems (based on kqueue).
netpollinit
- Initialize a
kqueue
descriptor, and setCLOSEXEC
flag on it. - Initialize a non-blocking pipe, and use the reader/writer for
netpollBreak
.netpollBreak
will try to write to the pipe and interrupt thekevent
.
netpoll
netpoll
is used to check the connections and return a list of g
ready to run. It can block for delay
ns at most.
The delay
parameter will be passed to kevent
syscall.
- Call
kevent
, fetch at most 64keventt
. - Iterate through each
keventt
.- If it’s a blocking call and there’s some data on
netpollBreakRd
, read 16-byte data from it. - Get the
mode
value based onkeventt.filter
. - Get the
pollDesc
information fromkeventt.udata
. - Call
netpollready
to populate thegList
.
- If it’s a blocking call and there’s some data on
- Return the
gList
.
netpollready
netpollready
calls netpollunlock
to swap the pending g
of pollDesc
to pdReady
, and return the pending g
.
netpollblock
- Tries to swap the pending
g
ofpollDesc
topdWaiting
, or return immediately if it’spdReady
. gopark
.- Check the pending
g
and return its status.
internal/poll.FD
poll.FD
is the underlying implementation of file descriptor used by net
package.
Open
- If the
FD
is not pollable, there’s nothing to do. - Initialize a
pollDesc
and use it asruntimeCtx
. This is done bypoll_runtime_pollOpen
:- Get a
pollDesc
from cache. - Lock the `pollDesc, set the file descriptor and initialize all other fields.
- Register read and write event with
kevent
.
- Get a
Close
- Call
increfAndClose
, wake up all waiters and notify the closing status. - Call
poll_runtime_pollUnblock
, wait for the g ready to consume thepollDesc
, and schedule theseg
to run later. - Release the
FD
, and return the underlyingpollDesc
back to the cache, then close the system’s file descriptor. - Wait for the close semaphore.
Read
- Acquire the read lock.
- Reset the descriptor mode to
r
. - Do syscall to read the file descriptor, block and wait if necessary.
Write
- Acquire the write lock.
- Reset the descriptor mode to
w
. - Do syscall to write the file descriptor, block and wait if necessary.