summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liechti <cliechti@gmx.net>2016-09-17 16:42:27 +0200
committerChris Liechti <cliechti@gmx.net>2016-09-17 16:42:27 +0200
commit2a7ed538a2c4e31c4297ee0a0c691ba92b967baf (patch)
treed4bda557d0a400c2ddfa0b0f53b49807452570bd
parentab1ff4887308bc49ba2d044b1cbb9844cb376ab8 (diff)
downloadpyserial-git-2a7ed538a2c4e31c4297ee0a0c691ba92b967baf.tar.gz
win32: handle additional errors in non-blocking mode, see #162
-rw-r--r--serial/serialwin32.py22
-rw-r--r--serial/win32.py4
2 files changed, 19 insertions, 7 deletions
diff --git a/serial/serialwin32.py b/serial/serialwin32.py
index 2de6a4b..c601c64 100644
--- a/serial/serialwin32.py
+++ b/serial/serialwin32.py
@@ -309,21 +309,29 @@ class Serial(SerialBase):
if data:
#~ win32event.ResetEvent(self._overlapped_write.hEvent)
n = win32.DWORD()
- err = win32.WriteFile(self._port_handle, data, len(data), ctypes.byref(n), self._overlapped_write)
- if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:
- raise SerialException("WriteFile failed ({!r})".format(ctypes.WinError()))
+ success = win32.WriteFile(self._port_handle, data, len(data), ctypes.byref(n), self._overlapped_write)
if self._write_timeout != 0: # if blocking (None) or w/ write timeout (>0)
+ if not success and win32.GetLastError() != win32.ERROR_IO_PENDING:
+ raise SerialException("WriteFile failed ({!r})".format(ctypes.WinError()))
+
# Wait for the write to complete.
#~ win32.WaitForSingleObject(self._overlapped_write.hEvent, win32.INFINITE)
- err = win32.GetOverlappedResult(self._port_handle, self._overlapped_write, ctypes.byref(n), True)
+ win32.GetOverlappedResult(self._port_handle, self._overlapped_write, ctypes.byref(n), True)
if win32.GetLastError() == win32.ERROR_OPERATION_ABORTED:
return n.value # canceled IO is no error
if n.value != len(data):
raise writeTimeoutError
return n.value
else:
- # no info on true length provided by OS function in async mode
- return len(data)
+ errorcode = win32.ERROR_SUCCESS if success else win32.GetLastError()
+ if errorcode in (win32.ERROR_INVALID_USER_BUFFER, win32.ERROR_NOT_ENOUGH_MEMORY,
+ win32.ERROR_OPERATION_ABORTED):
+ return 0
+ elif errorcode in (win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING)
+ # no info on true length provided by OS function in async mode
+ return len(data)
+ else:
+ raise SerialException("WriteFile failed ({!r})".format(ctypes.WinError()))
else:
return 0
@@ -335,7 +343,7 @@ class Serial(SerialBase):
while self.out_waiting:
time.sleep(0.05)
# XXX could also use WaitCommEvent with mask EV_TXEMPTY, but it would
- # require overlapped IO and its also only possible to set a single mask
+ # require overlapped IO and it's also only possible to set a single mask
# on the port---
def reset_input_buffer(self):
diff --git a/serial/win32.py b/serial/win32.py
index 31f21ee..905ce0f 100644
--- a/serial/win32.py
+++ b/serial/win32.py
@@ -218,10 +218,14 @@ FILE_FLAG_OVERLAPPED = 1073741824 # Variable c_int
EV_DSR = 16 # Variable c_int
MAXDWORD = 4294967295 # Variable c_uint
EV_RLSD = 32 # Variable c_int
+
ERROR_SUCCESS = 0
+ERROR_NOT_ENOUGH_MEMORY = 8
ERROR_OPERATION_ABORTED = 995
ERROR_IO_INCOMPLETE = 996
ERROR_IO_PENDING = 997 # Variable c_long
+ERROR_INVALID_USER_BUFFER = 1784
+
MS_CTS_ON = 16 # Variable c_ulong
EV_EVENT1 = 2048 # Variable c_int
EV_RX80FULL = 1024 # Variable c_int