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()
71
72
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()
134
135
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