Skip to content

Commit 695e7d8

Browse files
committed
update netpoll
1 parent d5d604c commit 695e7d8

File tree

1 file changed

+96
-3
lines changed

1 file changed

+96
-3
lines changed

netpoll.md

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -638,8 +638,8 @@ func (pd *pollDesc) wait(mode int, isFile bool) error {
638638
#### 就续通知
639639

640640
```go
641-
// polls for ready network connections
642-
// returns list of goroutines that become runnable
641+
// poll 已经就绪的网络连接
642+
// 返回那些已经可以跑的 goroutine 列表
643643
func netpoll(block bool) *g {
644644
if epfd == -1 {
645645
return nil
@@ -683,7 +683,7 @@ retry:
683683
return gp.ptr()
684684
}
685685

686-
// make pd ready, newly runnable goroutines (if any) are returned in rg/wg
686+
// pd 就续,新的可以运行的 goroutine 会 set 到 wg/rg
687687
// May run during STW, so write barriers are not allowed.
688688
//go:nowritebarrier
689689
func netpollready(gpp *guintptr, pd *pollDesc, mode int32) {
@@ -1121,3 +1121,96 @@ func ready(gp *g, traceskip int, next bool) {
11211121
```
11221122

11231123
### 连接关闭
1124+
1125+
```go
1126+
// Close closes the connection.
1127+
func (c *conn) Close() error {
1128+
if !c.ok() {
1129+
return syscall.EINVAL
1130+
}
1131+
err := c.fd.Close()
1132+
if err != nil {
1133+
err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
1134+
}
1135+
return err
1136+
}
1137+
```
1138+
1139+
```go
1140+
func (fd *netFD) Close() error {
1141+
runtime.SetFinalizer(fd, nil)
1142+
return fd.pfd.Close()
1143+
}
1144+
```
1145+
1146+
```go
1147+
// Close closes the FD. The underlying file descriptor is closed by the
1148+
// destroy method when there are no remaining references.
1149+
func (fd *FD) Close() error {
1150+
if !fd.fdmu.increfAndClose() {
1151+
return errClosing(fd.isFile)
1152+
}
1153+
1154+
// Unblock any I/O. Once it all unblocks and returns,
1155+
// so that it cannot be referring to fd.sysfd anymore,
1156+
// the final decref will close fd.sysfd. This should happen
1157+
// fairly quickly, since all the I/O is non-blocking, and any
1158+
// attempts to block in the pollDesc will return errClosing(fd.isFile).
1159+
fd.pd.evict()
1160+
1161+
// The call to decref will call destroy if there are no other
1162+
// references.
1163+
err := fd.decref()
1164+
1165+
// Wait until the descriptor is closed. If this was the only
1166+
// reference, it is already closed. Only wait if the file has
1167+
// not been set to blocking mode, as otherwise any current I/O
1168+
// may be blocking, and that would block the Close.
1169+
if !fd.isBlocking {
1170+
runtime_Semacquire(&fd.csema)
1171+
}
1172+
1173+
return err
1174+
}
1175+
```
1176+
1177+
```go
1178+
// Evict evicts fd from the pending list, unblocking any I/O running on fd.
1179+
func (pd *pollDesc) evict() {
1180+
if pd.runtimeCtx == 0 {
1181+
return
1182+
}
1183+
runtime_pollUnblock(pd.runtimeCtx)
1184+
}
1185+
```
1186+
1187+
```go
1188+
//go:linkname poll_runtime_pollUnblock internal/poll.runtime_pollUnblock
1189+
func poll_runtime_pollUnblock(pd *pollDesc) {
1190+
lock(&pd.lock)
1191+
if pd.closing {
1192+
throw("runtime: unblock on closing polldesc")
1193+
}
1194+
pd.closing = true
1195+
pd.seq++
1196+
var rg, wg *g
1197+
atomicstorep(unsafe.Pointer(&rg), nil) // full memory barrier between store to closing and read of rg/wg in netpollunblock
1198+
rg = netpollunblock(pd, 'r', false)
1199+
wg = netpollunblock(pd, 'w', false)
1200+
if pd.rt.f != nil {
1201+
deltimer(&pd.rt)
1202+
pd.rt.f = nil
1203+
}
1204+
if pd.wt.f != nil {
1205+
deltimer(&pd.wt)
1206+
pd.wt.f = nil
1207+
}
1208+
unlock(&pd.lock)
1209+
if rg != nil {
1210+
netpollgoready(rg, 3)
1211+
}
1212+
if wg != nil {
1213+
netpollgoready(wg, 3)
1214+
}
1215+
}
1216+
```

0 commit comments

Comments
 (0)