@@ -863,22 +863,22 @@ func dropg() {
863
863
### 读写超时
864
864
865
865
``` 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 值的话永远都不会超时
868
868
func (c *Conn ) SetReadDeadline (t time .Time ) error {
869
869
return c.conn .SetReadDeadline (t)
870
870
}
871
871
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 状态会被破坏,未来的所有写都会返回相同的错误
875
875
func (c *Conn ) SetWriteDeadline (t time .Time ) error {
876
876
return c.conn .SetWriteDeadline (t)
877
877
}
878
878
```
879
879
880
880
``` go
881
- // SetReadDeadline implements the Conn SetReadDeadline method.
881
+ // 实现 Conn 接口中的方法
882
882
func (c *conn ) SetReadDeadline (t time .Time ) error {
883
883
if !c.ok () {
884
884
return syscall.EINVAL
@@ -889,7 +889,7 @@ func (c *conn) SetReadDeadline(t time.Time) error {
889
889
return nil
890
890
}
891
891
892
- // SetWriteDeadline implements the Conn SetWriteDeadline method.
892
+ // 实现 Conn 接口中的方法
893
893
func (c *conn ) SetWriteDeadline (t time .Time ) error {
894
894
if !c.ok () {
895
895
return syscall.EINVAL
@@ -902,12 +902,12 @@ func (c *conn) SetWriteDeadline(t time.Time) error {
902
902
```
903
903
904
904
``` go
905
- // SetReadDeadline sets the read deadline associated with fd.
905
+ // 设置关联 fd 的读取 deadline
906
906
func (fd *FD ) SetReadDeadline (t time .Time ) error {
907
907
return setDeadlineImpl (fd, t, ' r' )
908
908
}
909
909
910
- // SetWriteDeadline sets the write deadline associated with fd.
910
+ // 设置关联 fd 的写入 deadline
911
911
func (fd *FD ) SetWriteDeadline (t time .Time ) error {
912
912
return setDeadlineImpl (fd, t, ' w' )
913
913
}
@@ -918,11 +918,15 @@ func setDeadlineImpl(fd *FD, t time.Time, mode int) error {
918
918
diff := int64 (time.Until (t))
919
919
d := runtimeNano () + diff
920
920
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 到最大的可能的值
923
922
d = 1 <<63 - 1
924
923
}
925
924
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
+ // }
926
930
d = 0
927
931
}
928
932
if err := fd.incref (); err != nil {
@@ -946,23 +950,27 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
946
950
return
947
951
}
948
952
pd.seq ++ // invalidate current timers
949
- // Reset current timers.
953
+ // 重置当前的 timer
950
954
if pd.rt .f != nil {
955
+ // 删除 pollDesc 相关的 read timer
951
956
deltimer (&pd.rt )
952
957
pd.rt .f = nil
953
958
}
954
959
if pd.wt .f != nil {
960
+ // 删除 pollDesc 相关的 write timer
955
961
deltimer (&pd.wt )
956
962
pd.wt .f = nil
957
963
}
958
- // Setup new timers.
964
+ // 设置新 timer
959
965
if d != 0 && d <= nanotime () {
960
966
d = -1
961
967
}
962
968
if mode == ' r' || mode == ' r' +' w' {
969
+ // 记录 read deadline
963
970
pd.rd = d
964
971
}
965
972
if mode == ' w' || mode == ' r' +' w' {
973
+ // 记录 write deadline
966
974
pd.wd = d
967
975
}
968
976
if pd.rd > 0 && pd.rd == pd.wd {
@@ -973,6 +981,7 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
973
981
// if they differ the descriptor was reused or timers were reset.
974
982
pd.rt .arg = pd
975
983
pd.rt .seq = pd.seq
984
+ // 插入 timer 到时间堆
976
985
addtimer (&pd.rt )
977
986
} else {
978
987
if pd.rd > 0 {
@@ -1009,6 +1018,8 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
1009
1018
}
1010
1019
```
1011
1020
1021
+ 根据 read deadline 和 write deadline 给要插入时间堆的 timer 设置不同的回调函数。
1022
+
1012
1023
``` go
1013
1024
func netpollDeadline (arg interface {}, seq uintptr ) {
1014
1025
netpolldeadlineimpl (arg.(*pollDesc), seq, true , true )
@@ -1017,8 +1028,14 @@ func netpollDeadline(arg interface{}, seq uintptr) {
1017
1028
func netpollReadDeadline (arg interface {}, seq uintptr ) {
1018
1029
netpolldeadlineimpl (arg.(*pollDesc), seq, true , false )
1019
1030
}
1031
+
1032
+ func netpollWriteDeadline (arg interface {}, seq uintptr ) {
1033
+ netpolldeadlineimpl (arg.(*pollDesc), seq, false , true )
1034
+ }
1020
1035
```
1021
1036
1037
+ 调用最终的实现函数:
1038
+
1022
1039
``` go
1023
1040
func netpolldeadlineimpl (pd *pollDesc , seq uintptr , read , write bool ) {
1024
1041
lock (&pd.lock )
@@ -1048,10 +1065,15 @@ func netpolldeadlineimpl(pd *pollDesc, seq uintptr, read, write bool) {
1048
1065
wg = netpollunblock (pd, ' w' , false )
1049
1066
}
1050
1067
unlock (&pd.lock )
1068
+ // rg 和 wg 是通过 netpollunblock 从 pollDesc 结构中捞出来的
1051
1069
if rg != nil {
1070
+ // 恢复 goroutine 执行现场
1071
+ // 继续执行
1052
1072
netpollgoready (rg, 0 )
1053
1073
}
1054
1074
if wg != nil {
1075
+ // 恢复 goroutine 执行现场
1076
+ // 继续执行
1055
1077
netpollgoready (wg, 0 )
1056
1078
}
1057
1079
}
@@ -1064,20 +1086,18 @@ func netpollgoready(gp *g, traceskip int) {
1064
1086
}
1065
1087
1066
1088
func goready (gp *g , traceskip int ) {
1089
+ // switch -> g0
1067
1090
systemstack (func () {
1068
1091
ready (gp, traceskip, true )
1069
1092
})
1070
1093
}
1071
1094
1072
1095
// Mark gp ready to run.
1073
1096
func ready (gp *g , traceskip int , next bool ) {
1074
- if trace.enabled {
1075
- traceGoUnpark (gp, traceskip)
1076
- }
1077
1097
1078
1098
status := readgstatus (gp)
1079
1099
1080
- // Mark runnable.
1100
+ // 标记为 runnable
1081
1101
_g_ := getg ()
1082
1102
_g_.m .locks ++ // disable preemption because it can be holding p in a local var
1083
1103
if status&^_Gscan != _Gwaiting {
@@ -1087,8 +1107,10 @@ func ready(gp *g, traceskip int, next bool) {
1087
1107
1088
1108
// status is Gwaiting or Gscanwaiting, make Grunnable and put on runq
1089
1109
casgstatus (gp, _Gwaiting, _Grunnable)
1110
+ // 放到执行队列里
1090
1111
runqput (_g_.m .p .ptr (), gp, next)
1091
1112
if atomic.Load (&sched.npidle ) != 0 && atomic.Load (&sched.nmspinning ) == 0 {
1113
+ // 如果有空闲的 p,那么就叫起床干活
1092
1114
wakep ()
1093
1115
}
1094
1116
_g_.m .locks --
@@ -1097,3 +1119,5 @@ func ready(gp *g, traceskip int, next bool) {
1097
1119
}
1098
1120
}
1099
1121
```
1122
+
1123
+ ### 连接关闭
0 commit comments