4
4
5
5
import win32file
6
6
import win32pipe
7
+ import pywintypes
8
+ import win32event
9
+ import win32api
7
10
8
11
cERROR_PIPE_BUSY = 0xe7
9
12
cSECURITY_SQOS_PRESENT = 0x100000
@@ -54,7 +57,9 @@ def connect(self, address, retry_count=0):
54
57
0 ,
55
58
None ,
56
59
win32file .OPEN_EXISTING ,
57
- cSECURITY_ANONYMOUS | cSECURITY_SQOS_PRESENT ,
60
+ (cSECURITY_ANONYMOUS
61
+ | cSECURITY_SQOS_PRESENT
62
+ | win32file .FILE_FLAG_OVERLAPPED ),
58
63
0
59
64
)
60
65
except win32pipe .error as e :
@@ -131,22 +136,37 @@ def recv_into(self, buf, nbytes=0):
131
136
if not isinstance (buf , memoryview ):
132
137
readbuf = memoryview (buf )
133
138
134
- err , data = win32file .ReadFile (
135
- self ._handle ,
136
- readbuf [:nbytes ] if nbytes else readbuf
137
- )
138
- return len (data )
139
-
140
- def _recv_into_py2 (self , buf , nbytes ):
141
- err , data = win32file .ReadFile (self ._handle , nbytes or len (buf ))
142
- n = len (data )
143
- buf [:n ] = data
144
- return n
139
+ event = win32event .CreateEvent (None , True , True , None )
140
+ try :
141
+ overlapped = pywintypes .OVERLAPPED ()
142
+ overlapped .hEvent = event
143
+ err , data = win32file .ReadFile (
144
+ self ._handle ,
145
+ readbuf [:nbytes ] if nbytes else readbuf ,
146
+ overlapped
147
+ )
148
+ wait_result = win32event .WaitForSingleObject (event , self ._timeout )
149
+ if wait_result == win32event .WAIT_TIMEOUT :
150
+ win32file .CancelIo (self ._handle )
151
+ raise TimeoutError
152
+ return win32file .GetOverlappedResult (self ._handle , overlapped , 0 )
153
+ finally :
154
+ win32api .CloseHandle (event )
145
155
146
156
@check_closed
147
157
def send (self , string , flags = 0 ):
148
- err , nbytes = win32file .WriteFile (self ._handle , string )
149
- return nbytes
158
+ event = win32event .CreateEvent (None , True , True , None )
159
+ try :
160
+ overlapped = pywintypes .OVERLAPPED ()
161
+ overlapped .hEvent = event
162
+ win32file .WriteFile (self ._handle , string , overlapped )
163
+ wait_result = win32event .WaitForSingleObject (event , self ._timeout )
164
+ if wait_result == win32event .WAIT_TIMEOUT :
165
+ win32file .CancelIo (self ._handle )
166
+ raise TimeoutError
167
+ return win32file .GetOverlappedResult (self ._handle , overlapped , 0 )
168
+ finally :
169
+ win32api .CloseHandle (event )
150
170
151
171
@check_closed
152
172
def sendall (self , string , flags = 0 ):
@@ -165,15 +185,12 @@ def setblocking(self, flag):
165
185
def settimeout (self , value ):
166
186
if value is None :
167
187
# Blocking mode
168
- self ._timeout = win32pipe . NMPWAIT_WAIT_FOREVER
188
+ self ._timeout = win32event . INFINITE
169
189
elif not isinstance (value , (float , int )) or value < 0 :
170
190
raise ValueError ('Timeout value out of range' )
171
- elif value == 0 :
172
- # Non-blocking mode
173
- self ._timeout = win32pipe .NMPWAIT_NO_WAIT
174
191
else :
175
192
# Timeout mode - Value converted to milliseconds
176
- self ._timeout = value * 1000
193
+ self ._timeout = int ( value * 1000 )
177
194
178
195
def gettimeout (self ):
179
196
return self ._timeout
0 commit comments