nail down select() on EOF: occasionally a channel would be closed remotely but select() wouldn't trigger.  when a channel gets EOF or is closed, set the pipe FOREVER.
This commit is contained in:
Robey Pointer 2005-12-02 12:42:42 -08:00
parent ee8a4e4b2b
commit e7a45fee60
2 changed files with 15 additions and 3 deletions

View File

@ -996,7 +996,7 @@ class Channel (object):
self.in_buffer_cv.notifyAll() self.in_buffer_cv.notifyAll()
self.in_stderr_buffer_cv.notifyAll() self.in_stderr_buffer_cv.notifyAll()
if self.pipe is not None: if self.pipe is not None:
self.pipe.set() self.pipe.set_forever()
finally: finally:
self.lock.release() self.lock.release()
self._log(DEBUG, 'EOF received') self._log(DEBUG, 'EOF received')
@ -1022,6 +1022,8 @@ class Channel (object):
self.in_buffer_cv.notifyAll() self.in_buffer_cv.notifyAll()
self.in_stderr_buffer_cv.notifyAll() self.in_stderr_buffer_cv.notifyAll()
self.out_buffer_cv.notifyAll() self.out_buffer_cv.notifyAll()
if self.pipe is not None:
self.pipe.set_forever()
def _send_eof(self): def _send_eof(self):
# you are holding the lock. # you are holding the lock.

View File

@ -36,6 +36,7 @@ class PosixPipe (object):
def __init__ (self): def __init__ (self):
self._rfd, self._wfd = os.pipe() self._rfd, self._wfd = os.pipe()
self._set = False self._set = False
self._forever = False
def close (self): def close (self):
os.close(self._rfd) os.close(self._rfd)
@ -45,7 +46,7 @@ class PosixPipe (object):
return self._rfd return self._rfd
def clear (self): def clear (self):
if not self._set: if not self._set or self._forever:
return return
os.read(self._rfd, 1) os.read(self._rfd, 1)
self._set = False self._set = False
@ -55,6 +56,10 @@ class PosixPipe (object):
return return
self._set = True self._set = True
os.write(self._wfd, '*') os.write(self._wfd, '*')
def set_forever (self):
self._forever = True
self.set()
class WindowsPipe (object): class WindowsPipe (object):
@ -74,6 +79,7 @@ class WindowsPipe (object):
self._wsock, addr = serv.accept() self._wsock, addr = serv.accept()
serv.close() serv.close()
self._set = False self._set = False
self._forever = False
def close (self): def close (self):
self._rsock.close() self._rsock.close()
@ -83,7 +89,7 @@ class WindowsPipe (object):
return self._rsock.fileno() return self._rsock.fileno()
def clear (self): def clear (self):
if not self._set: if not self._set or self._forever:
return return
self._rsock.recv(1) self._rsock.recv(1)
self._set = False self._set = False
@ -93,3 +99,7 @@ class WindowsPipe (object):
return return
self._set = True self._set = True
self._wsock.send('*') self._wsock.send('*')
def set_forever (self):
self._forever = True
self.set()