@@ -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."""
@@ -185,6 +193,13 @@ def update(self, timeout=0):
185
193
r = poll .poll (timeout )
186
194
poll .unregister (self .sock .sock )
187
195
else :
196
+ # select.select() does not work with negative timeouts, when a negative value is
197
+ # given select.epoll() and select.poll() are blocking until there is an event for
198
+ # the poll object, therefore set the timeout to None in order to have the same
199
+ # behaviour when select.select() is used
200
+ if timeout is not None and timeout < 0 :
201
+ timeout = None
202
+
188
203
r , _ , _ = select .select (
189
204
(self .sock .sock , ), (), (), timeout )
190
205
@@ -213,10 +228,11 @@ def update(self, timeout=0):
213
228
def run_forever (self , timeout = None ):
214
229
"""Wait till connection is closed or timeout reached. Buffer any input
215
230
received during this time."""
216
- if timeout :
231
+ if timeout is not None :
217
232
start = time .time ()
218
233
while self .is_open () and time .time () - start < timeout :
219
- self .update (timeout = (timeout - time .time () + start ))
234
+ # the timeout here should never be negative, because otherwise this method could block indefinitly
235
+ self .update (timeout = max (timeout - time .time () + start , 0 ))
220
236
else :
221
237
while self .is_open ():
222
238
self .update (timeout = None )
0 commit comments