Skip to content

Commit d5d604c

Browse files
committed
update netpoll
1 parent 6e3b4fc commit d5d604c

File tree

1 file changed

+41
-17
lines changed

1 file changed

+41
-17
lines changed

netpoll.md

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -863,22 +863,22 @@ func dropg() {
863863
### 读写超时
864864

865865
```go
866-
// SetReadDeadline sets the read deadline on the underlying connection.
867-
// A zero value for t means Read will not time out.
866+
// 设置底层连接的读超时
867+
// 超时时间是 0 值的话永远都不会超时
868868
func (c *Conn) SetReadDeadline(t time.Time) error {
869869
return c.conn.SetReadDeadline(t)
870870
}
871871

872-
// SetWriteDeadline sets the write deadline on the underlying connection.
873-
// A zero value for t means Write will not time out.
874-
// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
872+
// 设置底层连接的读超时
873+
// 超时时间是 0 值的话永远都不会超时
874+
// 写超时发生之后, TLS 状态会被破坏,未来的所有写都会返回相同的错误
875875
func (c *Conn) SetWriteDeadline(t time.Time) error {
876876
return c.conn.SetWriteDeadline(t)
877877
}
878878
```
879879

880880
```go
881-
// SetReadDeadline implements the Conn SetReadDeadline method.
881+
// 实现 Conn 接口中的方法
882882
func (c *conn) SetReadDeadline(t time.Time) error {
883883
if !c.ok() {
884884
return syscall.EINVAL
@@ -889,7 +889,7 @@ func (c *conn) SetReadDeadline(t time.Time) error {
889889
return nil
890890
}
891891

892-
// SetWriteDeadline implements the Conn SetWriteDeadline method.
892+
// 实现 Conn 接口中的方法
893893
func (c *conn) SetWriteDeadline(t time.Time) error {
894894
if !c.ok() {
895895
return syscall.EINVAL
@@ -902,12 +902,12 @@ func (c *conn) SetWriteDeadline(t time.Time) error {
902902
```
903903

904904
```go
905-
// SetReadDeadline sets the read deadline associated with fd.
905+
// 设置关联 fd 的读取 deadline
906906
func (fd *FD) SetReadDeadline(t time.Time) error {
907907
return setDeadlineImpl(fd, t, 'r')
908908
}
909909

910-
// SetWriteDeadline sets the write deadline associated with fd.
910+
// 设置关联 fd 的写入 deadline
911911
func (fd *FD) SetWriteDeadline(t time.Time) error {
912912
return setDeadlineImpl(fd, t, 'w')
913913
}
@@ -918,11 +918,15 @@ func setDeadlineImpl(fd *FD, t time.Time, mode int) error {
918918
diff := int64(time.Until(t))
919919
d := runtimeNano() + diff
920920
if d <= 0 && diff > 0 {
921-
// If the user has a deadline in the future, but the delay calculation
922-
// overflows, then set the deadline to the maximum possible value.
921+
// 如果用户提供了未来的 deadline,但是 delay 计算溢出了,那么设置 dealine 到最大的可能的值
923922
d = 1<<63 - 1
924923
}
925924
if t.IsZero() {
925+
// IsZero reports whether t represents the zero time instant,
926+
// January 1, year 1, 00:00:00 UTC.
927+
// func (t Time) IsZero() bool {
928+
// return t.sec() == 0 && t.nsec() == 0
929+
// }
926930
d = 0
927931
}
928932
if err := fd.incref(); err != nil {
@@ -946,23 +950,27 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
946950
return
947951
}
948952
pd.seq++ // invalidate current timers
949-
// Reset current timers.
953+
// 重置当前的 timer
950954
if pd.rt.f != nil {
955+
// 删除 pollDesc 相关的 read timer
951956
deltimer(&pd.rt)
952957
pd.rt.f = nil
953958
}
954959
if pd.wt.f != nil {
960+
// 删除 pollDesc 相关的 write timer
955961
deltimer(&pd.wt)
956962
pd.wt.f = nil
957963
}
958-
// Setup new timers.
964+
// 设置新 timer
959965
if d != 0 && d <= nanotime() {
960966
d = -1
961967
}
962968
if mode == 'r' || mode == 'r'+'w' {
969+
// 记录 read deadline
963970
pd.rd = d
964971
}
965972
if mode == 'w' || mode == 'r'+'w' {
973+
// 记录 write deadline
966974
pd.wd = d
967975
}
968976
if pd.rd > 0 && pd.rd == pd.wd {
@@ -973,6 +981,7 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
973981
// if they differ the descriptor was reused or timers were reset.
974982
pd.rt.arg = pd
975983
pd.rt.seq = pd.seq
984+
// 插入 timer 到时间堆
976985
addtimer(&pd.rt)
977986
} else {
978987
if pd.rd > 0 {
@@ -1009,6 +1018,8 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
10091018
}
10101019
```
10111020

1021+
根据 read deadline 和 write deadline 给要插入时间堆的 timer 设置不同的回调函数。
1022+
10121023
```go
10131024
func netpollDeadline(arg interface{}, seq uintptr) {
10141025
netpolldeadlineimpl(arg.(*pollDesc), seq, true, true)
@@ -1017,8 +1028,14 @@ func netpollDeadline(arg interface{}, seq uintptr) {
10171028
func netpollReadDeadline(arg interface{}, seq uintptr) {
10181029
netpolldeadlineimpl(arg.(*pollDesc), seq, true, false)
10191030
}
1031+
1032+
func netpollWriteDeadline(arg interface{}, seq uintptr) {
1033+
netpolldeadlineimpl(arg.(*pollDesc), seq, false, true)
1034+
}
10201035
```
10211036

1037+
调用最终的实现函数:
1038+
10221039
```go
10231040
func netpolldeadlineimpl(pd *pollDesc, seq uintptr, read, write bool) {
10241041
lock(&pd.lock)
@@ -1048,10 +1065,15 @@ func netpolldeadlineimpl(pd *pollDesc, seq uintptr, read, write bool) {
10481065
wg = netpollunblock(pd, 'w', false)
10491066
}
10501067
unlock(&pd.lock)
1068+
// rg 和 wg 是通过 netpollunblock 从 pollDesc 结构中捞出来的
10511069
if rg != nil {
1070+
// 恢复 goroutine 执行现场
1071+
// 继续执行
10521072
netpollgoready(rg, 0)
10531073
}
10541074
if wg != nil {
1075+
// 恢复 goroutine 执行现场
1076+
// 继续执行
10551077
netpollgoready(wg, 0)
10561078
}
10571079
}
@@ -1064,20 +1086,18 @@ func netpollgoready(gp *g, traceskip int) {
10641086
}
10651087

10661088
func goready(gp *g, traceskip int) {
1089+
// switch -> g0
10671090
systemstack(func() {
10681091
ready(gp, traceskip, true)
10691092
})
10701093
}
10711094

10721095
// Mark gp ready to run.
10731096
func ready(gp *g, traceskip int, next bool) {
1074-
if trace.enabled {
1075-
traceGoUnpark(gp, traceskip)
1076-
}
10771097

10781098
status := readgstatus(gp)
10791099

1080-
// Mark runnable.
1100+
// 标记为 runnable
10811101
_g_ := getg()
10821102
_g_.m.locks++ // disable preemption because it can be holding p in a local var
10831103
if status&^_Gscan != _Gwaiting {
@@ -1087,8 +1107,10 @@ func ready(gp *g, traceskip int, next bool) {
10871107

10881108
// status is Gwaiting or Gscanwaiting, make Grunnable and put on runq
10891109
casgstatus(gp, _Gwaiting, _Grunnable)
1110+
// 放到执行队列里
10901111
runqput(_g_.m.p.ptr(), gp, next)
10911112
if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 {
1113+
// 如果有空闲的 p,那么就叫起床干活
10921114
wakep()
10931115
}
10941116
_g_.m.locks--
@@ -1097,3 +1119,5 @@ func ready(gp *g, traceskip int, next bool) {
10971119
}
10981120
}
10991121
```
1122+
1123+
### 连接关闭

0 commit comments

Comments
 (0)