- 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
kqueuedescriptor, and setCLOSEXECflag on it. - Initialize a non-blocking pipe, and use the reader/writer for
netpollBreak.netpollBreakwill 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
modevalue based onkeventt.filter. - Get the
pollDescinformation fromkeventt.udata. - Call
netpollreadyto 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
gofpollDesctopdWaiting, or return immediately if it’spdReady. gopark.- Check the pending
gand return its status.
internal/poll.FD
poll.FD is the underlying implementation of file descriptor used by net package.
Open
- If the
FDis not pollable, there’s nothing to do. - Initialize a
pollDescand use it asruntimeCtx. This is done bypoll_runtime_pollOpen:- Get a
pollDescfrom 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 thesegto run later. - Release the
FD, and return the underlyingpollDescback 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.