1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19  """ 
 20  Abstraction of a one-way pipe where the read end can be used in select(). 
 21  Normally this is trivial, but Windows makes it nearly impossible. 
 22   
 23  The pipe acts like an Event, which can be set or cleared. When set, the pipe 
 24  will trigger as readable in select(). 
 25  """ 
 26   
 27  import sys 
 28  import os 
 29  import socket 
 30   
 31   
 38   
 39   
 42          self._rfd, self._wfd = os.pipe() 
 43          self._set = False 
 44          self._forever = False 
 45          self._closed = False 
  46       
 48          os.close(self._rfd) 
 49          os.close(self._wfd) 
 50           
 51          self._closed = True 
  52       
 55   
 57          if not self._set or self._forever: 
 58              return 
 59          os.read(self._rfd, 1) 
 60          self._set = False 
  61       
 63          if self._set or self._closed: 
 64              return 
 65          self._set = True 
 66          os.write(self._wfd, '*') 
  67       
 69          self._forever = True 
 70          self.set() 
  74      """ 
 75      On Windows, only an OS-level "WinSock" may be used in select(), but reads 
 76      and writes must be to the actual socket object. 
 77      """ 
 79          serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
 80          serv.bind(('127.0.0.1', 0)) 
 81          serv.listen(1) 
 82       
 83           
 84          self._rsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
 85          self._rsock.connect(('127.0.0.1', serv.getsockname()[1])) 
 86       
 87          self._wsock, addr = serv.accept() 
 88          serv.close() 
 89          self._set = False 
 90          self._forever = False 
 91          self._closed = False 
  92       
 94          self._rsock.close() 
 95          self._wsock.close() 
 96           
 97          self._closed = True 
  98       
100          return self._rsock.fileno() 
 101   
103          if not self._set or self._forever: 
104              return 
105          self._rsock.recv(1) 
106          self._set = False 
 107       
109          if self._set or self._closed: 
110              return 
111          self._set = True 
112          self._wsock.send('*') 
 113   
115          self._forever = True 
116          self.set() 
  117   
118   
121          self._set = False 
122          self._partner = None 
123          self._pipe = pipe 
 124       
126          self._set = True 
127          if not self._partner._set: 
128              self._pipe.set() 
 129       
131          self._set = False 
132          if not self._partner._set: 
133              self._pipe.clear() 
 137      """ 
138      wraps a pipe into two pipe-like objects which are "or"d together to 
139      affect the real pipe. if either returned pipe is set, the wrapped pipe 
140      is set. when both are cleared, the wrapped pipe is cleared. 
141      """ 
142      p1 = OrPipe(pipe) 
143      p2 = OrPipe(pipe) 
144      p1._partner = p2 
145      p2._partner = p1 
146      return p1, p2 
 147