@@ -86,10 +86,10 @@ def read_channel(self, channel, timeout=0):
86
86
87
87
def readline_channel (self , channel , timeout = None ):
88
88
"""Read a line from a channel."""
89
- if timeout is None :
90
- timeout = float ( "inf" )
89
+ if timeout is not None and timeout < 0 :
90
+ timeout = None
91
91
start = time .time ()
92
- while self . is_open () and time .time () - start < timeout :
92
+ while timeout is None or time .time () - start < timeout :
93
93
if channel in self ._channels :
94
94
data = self ._channels [channel ]
95
95
if "\n " in data :
@@ -101,7 +101,15 @@ def readline_channel(self, channel, timeout=None):
101
101
else :
102
102
del self ._channels [channel ]
103
103
return ret
104
- self .update (timeout = (timeout - time .time () + start ))
104
+
105
+ if not self .is_open ():
106
+ return
107
+
108
+ if timeout is not None :
109
+ # the timeout here should never be negative, because otherwise this method could block indefinitly
110
+ self .update (timeout = max (timeout - time .time () + start , 0 ))
111
+ else :
112
+ self .update (timeout = None )
105
113
106
114
def write_channel (self , channel , data ):
107
115
"""Write data to a channel."""
@@ -187,6 +195,13 @@ def update(self, timeout=0):
187
195
r = poll .poll (timeout )
188
196
poll .unregister (self .sock .sock )
189
197
else :
198
+ # select.select() does not work with negative timeouts, when a negative value is
199
+ # given select.epoll() and select.poll() are blocking until there is an event for
200
+ # the poll object, therefore set the timeout to None in order to have the same
201
+ # behaviour when select.select() is used
202
+ if timeout is not None and timeout < 0 :
203
+ timeout = None
204
+
190
205
r , _ , _ = select .select (
191
206
(self .sock .sock , ), (), (), timeout )
192
207
@@ -215,10 +230,11 @@ def update(self, timeout=0):
215
230
def run_forever (self , timeout = None ):
216
231
"""Wait till connection is closed or timeout reached. Buffer any input
217
232
received during this time."""
218
- if timeout :
233
+ if timeout is not None :
219
234
start = time .time ()
220
235
while self .is_open () and time .time () - start < timeout :
221
- self .update (timeout = (timeout - time .time () + start ))
236
+ # the timeout here should never be negative, because otherwise this method could block indefinitly
237
+ self .update (timeout = max (timeout - time .time () + start , 0 ))
222
238
else :
223
239
while self .is_open ():
224
240
self .update (timeout = None )
0 commit comments