This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author sbt
Recipients jnoller, pitrou, sbt
Date 2011-06-13.18:53:15
SpamBayes Score 4.6580917e-10
Marked as misclassified No
Message-id <1307991196.59.0.849860111943.issue12328@psf.upfronthosting.co.za>
In-reply-to
Content
There are some problems with the new Windows overlapped implementation
of PipeConnection in the default branch.

1) poll(0) can return False when an empty string is in the pipe: if
   the next message in the pipe is b"" then PeekNamedPipe() returns
   (0, 0) which is indistiguishable from the case where the pipe is
   empty.

   This affects versions 2.6-3.2 of Python on Windows as well.  For
   old versions I would just document the fact that poll() will fail
   to see that there is data in the pipe if the next message is an
   empty string.  In practice this is not a big deal since pipes are
   primarily used for pickled objects which will never be the empty
   string.

2) _poll() forgets to check self._buffered, so it can return False
   even if there is buffered data.

3) Even if (2) is fixed, _poll() with a non-zero timeout can mess up
   message boundaries if the pipe contains messages of length zero or
   one.  To fix this overlapped_GetOverlappedResult() needs to be
   changed to not swallow and forget ERROR_MORE_DATA errors.

4) In _poll() there is a race condition: if the read operation
   completes after WaitForMultipleObjects() timesout, but before the
   operation is cancelled, then the data read will be discarded.

5) The code assumes that if CancelIo()/CancelIoEx() returns
   successfully then the OVERLAPPED structure and associated buffer
   may be deallocated immediately.  But the documentation says that if
   CancelIo()/CancelIoEx() succeeds then cancellation has only been
   *requested*:

     http://msdn.microsoft.com/en-us/library/aa363792%28v=vs.85%29.aspx

     If [CancelIoEx()] succeeds, the return value is nonzero. The
     cancel operation for all pending I/O operations issued by the
     calling thread for the specified file handle was successfully
     *requested*. The application must not free or reuse the
     OVERLAPPED structure associated with the canceled I/O operations
     until they have *completed*. The thread can use the
     GetOverlappedResult function to determine when the I/O operations
     themselves have been completed.

   We should wait for cancellation to *complete* by using
   GetOverlappedResult(..., TRUE), otherwise we risk a crash.  If the
   operation was cancelled then FALSE is returned with GetLastError()
   == ERROR_OPERATION_ABORTED.

   I would suggest making it a programming error for the overlapped
   object to be deallocated while the operation is still pending, and
   to print a RuntimeError if that happens.  (This does not prevent us
   from still trying to prevent a crash using CancelIoEx().)

6) Not a bug exactly, but poll(timeout) is no longer interruptible
   with Ctrl-C.  This also means that Queue.get() is no longer
   interruptible.

--

The unit tests attached pass on Unix.  On Windows versions up to 3.2,
only test_empty_string fails.  On Windows version 3.3 all three fail.
History
Date User Action Args
2011-06-13 18:53:16sbtsetrecipients: + sbt, pitrou, jnoller
2011-06-13 18:53:16sbtsetmessageid: <1307991196.59.0.849860111943.issue12328@psf.upfronthosting.co.za>
2011-06-13 18:53:16sbtlinkissue12328 messages
2011-06-13 18:53:15sbtcreate