Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2cbed00

Browse files
committed
Fixes for Windows (but also tested on Linux). Test suite now completes, and this module should not leak in the face of errors.
Checkin that replaces the INT_PTR types with HANDLEs still TBD (but as that is a "spelling" patch, rather than a functional one, I will commit it seperately.
1 parent af4cfae commit 2cbed00

1 file changed

Lines changed: 46 additions & 6 deletions

File tree

Modules/mmapmodule.c

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,14 @@ static void
6161
mmap_object_dealloc(mmap_object *m_obj)
6262
{
6363
#ifdef MS_WIN32
64-
UnmapViewOfFile (m_obj->data);
65-
CloseHandle (m_obj->map_handle);
66-
CloseHandle ((HANDLE)m_obj->file_handle);
64+
if (m_obj->data != NULL)
65+
UnmapViewOfFile (m_obj->data);
66+
if (m_obj->map_handle != INVALID_HANDLE_VALUE)
67+
CloseHandle (m_obj->map_handle);
68+
if ((HANDLE)m_obj->file_handle != INVALID_HANDLE_VALUE)
69+
CloseHandle ((HANDLE)m_obj->file_handle);
70+
if (m_obj->tagname)
71+
PyMem_Free(m_obj->tagname);
6772
#endif /* MS_WIN32 */
6873

6974
#ifdef UNIX
@@ -826,23 +831,57 @@ new_mmap_object(PyObject *self, PyObject *args)
826831
}
827832

828833
m_obj = PyObject_New (mmap_object, &mmap_object_type);
829-
834+
if (m_obj==NULL)
835+
return NULL;
836+
/* Set every field to an invalid marker, so we can safely
837+
destruct the object in the face of failure */
838+
m_obj->data = NULL;
839+
m_obj->file_handle = (INT_PTR)INVALID_HANDLE_VALUE;
840+
m_obj->map_handle = INVALID_HANDLE_VALUE;
841+
m_obj->tagname = NULL;
842+
830843
if (fh) {
831-
m_obj->file_handle = fh;
844+
/* It is necessary to duplicate the handle, so the
845+
Python code can close it on us */
846+
if (!DuplicateHandle(
847+
GetCurrentProcess(), /* source process handle */
848+
(HANDLE)fh, /* handle to be duplicated */
849+
GetCurrentProcess(), /* target proc handle */
850+
(LPHANDLE)&m_obj->file_handle, /* result */
851+
0, /* access - ignored due to options value */
852+
FALSE, /* inherited by child processes? */
853+
DUPLICATE_SAME_ACCESS)) { /* options */
854+
dwErr = GetLastError();
855+
Py_DECREF(m_obj);
856+
PyErr_SetFromWindowsErr(dwErr);
857+
return NULL;
858+
}
832859
if (!map_size) {
833860
m_obj->size = GetFileSize ((HANDLE)fh, NULL);
834861
} else {
835862
m_obj->size = map_size;
836863
}
837864
}
838865
else {
839-
m_obj->file_handle = (INT_PTR) -1;
840866
m_obj->size = map_size;
841867
}
842868

843869
/* set the initial position */
844870
m_obj->pos = (size_t) 0;
845871

872+
/* set the tag name */
873+
if (tagname != NULL) {
874+
m_obj->tagname = PyMem_Malloc(strlen(tagname)+1);
875+
if (m_obj->tagname == NULL) {
876+
PyErr_NoMemory();
877+
Py_DECREF(m_obj);
878+
return NULL;
879+
}
880+
strcpy(m_obj->tagname, tagname);
881+
}
882+
else
883+
m_obj->tagname = NULL;
884+
846885
m_obj->map_handle = CreateFileMapping ((HANDLE) m_obj->file_handle,
847886
NULL,
848887
PAGE_READWRITE,
@@ -863,6 +902,7 @@ new_mmap_object(PyObject *self, PyObject *args)
863902
} else {
864903
dwErr = GetLastError();
865904
}
905+
Py_DECREF(m_obj);
866906
PyErr_SetFromWindowsErr(dwErr);
867907
return (NULL);
868908
}

0 commit comments

Comments
 (0)