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
21 `select.select`. Normally this is trivial, but Windows makes it nearly
22 impossible.
23
24 The pipe acts like an Event, which can be set or cleared. When set, the pipe
25 will trigger as readable in `select <select.select>`.
26 """
27
28 import sys
29 import os
30 import socket
31
32
39
40
43 self._rfd, self._wfd = os.pipe()
44 self._set = False
45 self._forever = False
46 self._closed = False
47
49 os.close(self._rfd)
50 os.close(self._wfd)
51
52 self._closed = True
53
56
58 if not self._set or self._forever:
59 return
60 os.read(self._rfd, 1)
61 self._set = False
62
64 if self._set or self._closed:
65 return
66 self._set = True
67 os.write(self._wfd, b'*')
68
70 self._forever = True
71 self.set()
72
73
75 """
76 On Windows, only an OS-level "WinSock" may be used in select(), but reads
77 and writes must be to the actual socket object.
78 """
80 serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
81 serv.bind(('127.0.0.1', 0))
82 serv.listen(1)
83
84
85 self._rsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
86 self._rsock.connect(('127.0.0.1', serv.getsockname()[1]))
87
88 self._wsock, addr = serv.accept()
89 serv.close()
90 self._set = False
91 self._forever = False
92 self._closed = False
93
95 self._rsock.close()
96 self._wsock.close()
97
98 self._closed = True
99
101 return self._rsock.fileno()
102
104 if not self._set or self._forever:
105 return
106 self._rsock.recv(1)
107 self._set = False
108
110 if self._set or self._closed:
111 return
112 self._set = True
113 self._wsock.send(b'*')
114
116 self._forever = True
117 self.set()
118
119
122 self._set = False
123 self._partner = None
124 self._pipe = pipe
125
127 self._set = True
128 if not self._partner._set:
129 self._pipe.set()
130
132 self._set = False
133 if not self._partner._set:
134 self._pipe.clear()
135
136
138 """
139 wraps a pipe into two pipe-like objects which are "or"d together to
140 affect the real pipe. if either returned pipe is set, the wrapped pipe
141 is set. when both are cleared, the wrapped pipe is cleared.
142 """
143 p1 = OrPipe(pipe)
144 p2 = OrPipe(pipe)
145 p1._partner = p2
146 p2._partner = p1
147 return p1, p2
148