@@ -143,17 +143,26 @@ def stop(self):
143143 python2atexit .unregister (self .stop )
144144
145145 def select (self , * args , ** kwargs ):
146- try :
147- return select .select (* args , ** kwargs )
148- except select .error as ex :
149- # if the system call was interrupted, we'll return as a timeout
150- # in Python 3, system call interruptions are a native exception
151- # in Python 2, they are not
152- errnum = ex .errno if isinstance (ex , OSError ) else ex [0 ]
153- # to mimic a timeout, we return the same thing select would
154- if errnum == errno .EINTR :
155- return ([], [], [])
156- raise
146+ # select() takes no kwargs, so it will be in args
147+ timeout = args [3 ] if len (args ) == 4 else None
148+ # either the time to give up, or None
149+ end = (time .time () + timeout ) if timeout else None
150+ while end is None or time .time () < end :
151+ if end is not None :
152+ args = list (args ) # make a list, since tuples aren't mutable
153+ args [3 ] = end - time .time () # set the timeout to the remaining time
154+ try :
155+ return select .select (* args , ** kwargs )
156+ except select .error as ex :
157+ # if the system call was interrupted, we'll retry until timeout
158+ # in Python 3, system call interruptions are a native exception
159+ # in Python 2, they are not
160+ errnum = ex .errno if isinstance (ex , OSError ) else ex [0 ]
161+ if errnum == errno .EINTR :
162+ continue
163+ raise
164+ # if we hit our timeout, lets return as a timeout
165+ return ([], [], [])
157166
158167 def socket (self ):
159168 return utils .create_tcp_socket (socket )
0 commit comments