Bug in Win32file WaitCommEvent ???
Grant Edwards
grante at visi.com
Tue Nov 19 15:56:45 EST 2002
I'm trying to figure out how WaitCommEvent() works in Python,
and it looks like there's a problem when it's used in
overlapped mode.
My understanding is that (in C) you:
1) Call WaitCommEvent() and give it three parameters:
* File handle
* a pointer to where the output mask value is to be stored
* a pointer to an overlapped struct
2) WaitCommEvent() returns immediately.
3) Call one of the WaitXXX() functions to wait on the event in
the overloapped struct.
4) When the event is triggered WaitXXX() returns. Check the
value stored via the output mask pointer passed in 1)
above.
[I've gleaned most of this from
http://msdn.microsoft.com/library/en-us/devio/base/waitcommevent.asp]
What I can't figure out: How is this supposed to work in Python?
1 /* File : win32file.i */
[...]
2089 static PyObject *MyWaitCommEvent(PyObject *self, PyObject *args)
2090 {
2091 PyObject *obHandle, *obOverlapped = Py_None;
2092 if (!PyArg_ParseTuple(args, "O|O",
2093 &obHandle, // @pyparm <o PyHANDLE>|handle||The handle to the communications device.
2094 &obOverlapped))// @pyparm <o PyOVERLAPPED>|overlapped||This structure is required if hFile was opened with FILE_FLAG_OVERLAPPED.
2095 // <nl>If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the operation is complete.
2096 // <nl>If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, WaitCommEvent is performed as an overlapped operation. In this case, the OVERLAPPED structure must contain a handle to a manual-reset event object (created by using the CreateEvent function).
2097 // <nl>If hFile was not opened with FILE_FLAG_OVERLAPPED, WaitCommEvent does not return until one of the specified events or an error occurs.
2098 return NULL;
2099 HANDLE handle;
2100 if (!PyWinObject_AsHANDLE(obHandle, &handle, FALSE))
2101 return NULL;
2102 OVERLAPPED *poverlapped;
2103 if (!PyWinObject_AsOVERLAPPED(obOverlapped, &poverlapped, TRUE))
2104 return NULL;
2105 DWORD mask;
2106 BOOL ok;
2107 Py_BEGIN_ALLOW_THREADS
2108 ok = WaitCommEvent(handle, &mask, poverlapped);
2109 Py_END_ALLOW_THREADS
2110 DWORD rc = ok ? 0 : GetLastError();
2111 if (rc!=0 && rc != ERROR_IO_PENDING)
2112 return PyWin_SetAPIError("WaitCommError", rc);
2113 return Py_BuildValue("ll", rc, mask);
2114 }
I've been looking at the sources above, and the output mask
pointer passed in 1) points to a _local_ DWORD variable [lines
2105, 2108]. Right?
When used in overlapped mode, WaitCommEvent returns before the
event has happened (and therefore before the output mask value
has been written). What happens when the event actually occurs
[between 3) and 4) above] and Win32 writes the output mask
value? The mask pointer which Win32 has stashed away from the
call at 1) is no longer valid. I think. Maybe.
How _do_ you get the output mask value in overlapped mode in
Python?
In C, you do it by passing a mask pointer that points to a
variable whose lifetime extends past the point in time when the
event actually happens and the WaitXXX() call returns [and then
you check the output mask value].
Disclaimer: I'm a Unix guy and find the Win32 stuff to be
overly complex and baroque. Perhaps I haven't
understood the MSDN docs and the example C code
I've seen. If so, I'd be eternally grateful if you
could point me to decent docs for the Win32 serial
port API.
--
Grant Edwards grante Yow! Now KEN and BARBIE
at are PERMANENTLY ADDICTED to
visi.com MIND-ALTERING DRUGS...
More information about the Python-list
mailing list