@@ -65,56 +65,51 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool {
65
65
return C.FD_ISSET (handle, & set)
66
66
}
67
67
68
- // select_with_retry will retry the select if select is failing
69
- // due to interrupted system call. This can happen on signals
70
- // for example the GC Boehm uses signals internally on garbage
71
- // collection
72
68
[inline ]
73
- fn select_with_retry (handle int , test Select, timeout time.Duration) ? bool {
74
- mut retries := 10
75
- for retries > 0 {
69
+ fn select_deadline (handle int , test Select, deadline time.Time) ? bool {
70
+ // if we have a 0 deadline here then the timeout that was passed was infinite...
71
+ infinite := deadline.unix_time () == 0
72
+ for infinite || time.now () < = deadline {
73
+ timeout := if infinite { net.infinite_timeout } else { deadline - time.now () }
76
74
ready := @select (handle, test, timeout) or {
77
75
if err.code () == 4 {
78
- // signal! lets retry max 10 times
79
- // suspend thread with sleep to let the gc get
80
- // cycles in the case the Bohem gc is interupting
81
- time.sleep (1 * time.millisecond)
82
- retries - = 1
76
+ // Spurious wakeup from signal, keep waiting
83
77
continue
84
78
}
85
- // we got other error
79
+
80
+ // NOT a spurious wakeup
86
81
return err
87
82
}
83
+
88
84
return ready
89
85
}
90
- return error ('failed to @select more that three times due to interrupted system call' )
86
+
87
+ // Deadline elapsed
88
+ return false
91
89
}
92
90
93
91
// wait_for_common wraps the common wait code
94
92
fn wait_for_common (handle int , deadline time.Time, timeout time.Duration, test Select) ? {
95
- if deadline.unix == 0 {
96
- // do not accept negative timeout
97
- if timeout < 0 {
98
- return err_timed_out
99
- }
100
- ready := select_with_retry (handle, test, timeout) ?
101
- if ready {
102
- return
103
- }
104
- return err_timed_out
93
+ // Convert timeouts to deadlines
94
+ real_deadline := if timeout == net.infinite_timeout {
95
+ time.unix (0 )
96
+ } else if timeout == 0 {
97
+ // No timeout set, so assume deadline
98
+ deadline
99
+ } else if timeout < 0 {
100
+ // TODO(emily): Do something nicer here :)
101
+ panic ('invalid negative timeout' )
102
+ } else {
103
+ // timeout
104
+ time.now ().add (timeout)
105
105
}
106
- // Convert the deadline into a timeout
107
- // and use that
108
- d_timeout := deadline.unix - time.now ().unix
109
- if d_timeout < 0 {
110
- // deadline is in the past so this has already
111
- // timed out
112
- return err_timed_out
113
- }
114
- ready := select_with_retry (handle, test, timeout) ?
106
+
107
+ ready := select_deadline (handle, test, real_deadline) ?
108
+
115
109
if ready {
116
110
return
117
111
}
112
+
118
113
return err_timed_out
119
114
}
120
115
0 commit comments