summaryrefslogtreecommitdiffstats
path: root/Modules/_winapi.c
diff options
context:
space:
mode:
authorRichard Oudkerk <shibturn@gmail.com>2013-11-17 13:15:51 (GMT)
committerRichard Oudkerk <shibturn@gmail.com>2013-11-17 13:15:51 (GMT)
commit633db6f6a69fd44b4a27e7e216ff7a138f69aaf3 (patch)
tree15b77227b9654c7e1eab0694d39685c46b67b00e /Modules/_winapi.c
parent80b2aa0a4fef871c1775a16688030b6a3b26b99f (diff)
downloadcpython-633db6f6a69fd44b4a27e7e216ff7a138f69aaf3.zip
cpython-633db6f6a69fd44b4a27e7e216ff7a138f69aaf3.tar.gz
cpython-633db6f6a69fd44b4a27e7e216ff7a138f69aaf3.tar.bz2
Issue #19565: Prevent warnings at shutdown about pending overlapped ops.
Diffstat (limited to 'Modules/_winapi.c')
-rw-r--r--Modules/_winapi.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/Modules/_winapi.c b/Modules/_winapi.c
index 20d0063..724a478 100644
--- a/Modules/_winapi.c
+++ b/Modules/_winapi.c
@@ -107,17 +107,37 @@ overlapped_dealloc(OverlappedObject *self)
{
DWORD bytes;
int err = GetLastError();
+
if (self->pending) {
- /* make it a programming error to deallocate while operation
- is pending, even if we can safely cancel it */
if (check_CancelIoEx() &&
- Py_CancelIoEx(self->handle, &self->overlapped))
- GetOverlappedResult(self->handle, &self->overlapped, &bytes, TRUE);
- PyErr_SetString(PyExc_RuntimeError,
- "I/O operations still in flight while destroying "
- "Overlapped object, the process may crash");
- PyErr_WriteUnraisable(NULL);
+ Py_CancelIoEx(self->handle, &self->overlapped) &&
+ GetOverlappedResult(self->handle, &self->overlapped, &bytes, TRUE))
+ {
+ /* The operation is no longer pending -- nothing to do. */
+ }
+ else if (_Py_Finalizing == NULL)
+ {
+ /* The operation is still pending -- give a warning. This
+ will probably only happen on Windows XP. */
+ PyErr_SetString(PyExc_RuntimeError,
+ "I/O operations still in flight while destroying "
+ "Overlapped object, the process may crash");
+ PyErr_WriteUnraisable(NULL);
+ }
+ else
+ {
+ /* The operation is still pending, but the process is
+ probably about to exit, so we need not worry too much
+ about memory leaks. Leaking self prevents a potential
+ crash. This can happen when a daemon thread is cleaned
+ up at exit -- see #19565. We only expect to get here
+ on Windows XP. */
+ CloseHandle(self->overlapped.hEvent);
+ SetLastError(err);
+ return;
+ }
}
+
CloseHandle(self->overlapped.hEvent);
SetLastError(err);
if (self->write_buffer.obj)