diff options
author | Chris Liechti <cliechti@gmx.net> | 2016-09-17 16:42:27 +0200 |
---|---|---|
committer | Chris Liechti <cliechti@gmx.net> | 2016-09-17 16:42:27 +0200 |
commit | 2a7ed538a2c4e31c4297ee0a0c691ba92b967baf (patch) | |
tree | d4bda557d0a400c2ddfa0b0f53b49807452570bd | |
parent | ab1ff4887308bc49ba2d044b1cbb9844cb376ab8 (diff) | |
download | pyserial-git-2a7ed538a2c4e31c4297ee0a0c691ba92b967baf.tar.gz |
win32: handle additional errors in non-blocking mode, see #162
-rw-r--r-- | serial/serialwin32.py | 22 | ||||
-rw-r--r-- | serial/win32.py | 4 |
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 |