]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] bpo-40882: Fix a memory leak in SharedMemory on Windows (GH-20684) (#99973)
authorLuke Garland <luke.garland01@gmail.com>
Mon, 5 Dec 2022 12:38:25 +0000 (05:38 -0700)
committerGitHub <noreply@github.com>
Mon, 5 Dec 2022 12:38:25 +0000 (13:38 +0100)
bpo-40882: Fix a memory leak in SharedMemory on Windows (GH-20684)

In multiprocessing.shared_memory.SharedMemory(), the temporary view
returned by MapViewOfFile() should be unmapped when it is no longer
needed.

(cherry picked from commit 85c128e34daec7625b74746e127afa25888ccde1)

Co-authored-by: Zackery Spytz <zspytz@gmail.com>
Lib/multiprocessing/shared_memory.py
Misc/NEWS.d/next/Windows/2020-06-06-15-10-37.bpo-40882.UvNbdj.rst [new file with mode: 0644]
Modules/_winapi.c
Modules/clinic/_winapi.c.h

index 881f2001dd59800b020cc229b8bb78136c8db437..9a1e5aa17b87a232a831b5d250b8e0c2f15f574d 100644 (file)
@@ -173,7 +173,10 @@ class SharedMemory:
                     )
                 finally:
                     _winapi.CloseHandle(h_map)
-                size = _winapi.VirtualQuerySize(p_buf)
+                try:
+                    size = _winapi.VirtualQuerySize(p_buf)
+                finally:
+                    _winapi.UnmapViewOfFile(p_buf)
                 self._mmap = mmap.mmap(-1, size, tagname=name)
 
         self._size = size
diff --git a/Misc/NEWS.d/next/Windows/2020-06-06-15-10-37.bpo-40882.UvNbdj.rst b/Misc/NEWS.d/next/Windows/2020-06-06-15-10-37.bpo-40882.UvNbdj.rst
new file mode 100644 (file)
index 0000000..2670aee
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a memory leak in :class:`multiprocessing.shared_memory.SharedMemory` on
+Windows.
index 9b30a900326192751b0786c571b1921b06f4440a..f6bb07fd8b06ef31864f8ad2dfe4602dc00ba9f6 100644 (file)
@@ -1402,6 +1402,30 @@ _winapi_MapViewOfFile_impl(PyObject *module, HANDLE file_map,
     return address;
 }
 
+/*[clinic input]
+_winapi.UnmapViewOfFile
+
+    address: LPCVOID
+    /
+[clinic start generated code]*/
+
+static PyObject *
+_winapi_UnmapViewOfFile_impl(PyObject *module, LPCVOID address)
+/*[clinic end generated code: output=4f7e18ac75d19744 input=8c4b6119ad9288a3]*/
+{
+    BOOL success;
+
+    Py_BEGIN_ALLOW_THREADS
+    success = UnmapViewOfFile(address);
+    Py_END_ALLOW_THREADS
+
+    if (!success) {
+        return PyErr_SetFromWindowsErr(0);
+    }
+
+    Py_RETURN_NONE;
+}
+
 /*[clinic input]
 _winapi.OpenFileMapping -> HANDLE
 
@@ -2095,6 +2119,7 @@ static PyMethodDef winapi_functions[] = {
     _WINAPI_READFILE_METHODDEF
     _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF
     _WINAPI_TERMINATEPROCESS_METHODDEF
+    _WINAPI_UNMAPVIEWOFFILE_METHODDEF
     _WINAPI_VIRTUALQUERYSIZE_METHODDEF
     _WINAPI_WAITNAMEDPIPE_METHODDEF
     _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF
index 118e7bfd29fecfc2a85773a9487bf7a71f063909..5364d9a2d6ef78cc301b43a3a1bc11bb03e5bc47 100644 (file)
@@ -731,6 +731,32 @@ exit:
     return return_value;
 }
 
+PyDoc_STRVAR(_winapi_UnmapViewOfFile__doc__,
+"UnmapViewOfFile($module, address, /)\n"
+"--\n"
+"\n");
+
+#define _WINAPI_UNMAPVIEWOFFILE_METHODDEF    \
+    {"UnmapViewOfFile", (PyCFunction)_winapi_UnmapViewOfFile, METH_O, _winapi_UnmapViewOfFile__doc__},
+
+static PyObject *
+_winapi_UnmapViewOfFile_impl(PyObject *module, LPCVOID address);
+
+static PyObject *
+_winapi_UnmapViewOfFile(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    LPCVOID address;
+
+    if (!PyArg_Parse(arg, "" F_POINTER ":UnmapViewOfFile", &address)) {
+        goto exit;
+    }
+    return_value = _winapi_UnmapViewOfFile_impl(module, address);
+
+exit:
+    return return_value;
+}
+
 PyDoc_STRVAR(_winapi_OpenFileMapping__doc__,
 "OpenFileMapping($module, desired_access, inherit_handle, name, /)\n"
 "--\n"
@@ -1216,4 +1242,4 @@ _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=60b036183b92659e input=a9049054013a1b77]*/
+/*[clinic end generated code: output=9c08a7371fcf5dd4 input=a9049054013a1b77]*/