diff options
author | Mark Hammond <mhammond@skippinet.com.au> | 2000-07-30 02:22:43 (GMT) |
---|---|---|
committer | Mark Hammond <mhammond@skippinet.com.au> | 2000-07-30 02:22:43 (GMT) |
commit | 2cbed005b6303fa999076abd34e9c6e58d483d76 (patch) | |
tree | 6ca47ae8ca776e42941d4b7f5725232253d7489b | |
parent | af4cfae300846ecf6ad21946f52535fd69e1773b (diff) | |
download | cpython-2cbed005b6303fa999076abd34e9c6e58d483d76.zip cpython-2cbed005b6303fa999076abd34e9c6e58d483d76.tar.gz cpython-2cbed005b6303fa999076abd34e9c6e58d483d76.tar.bz2 |
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.
-rw-r--r-- | Modules/mmapmodule.c | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 772e2af..051a715 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -61,9 +61,14 @@ static void mmap_object_dealloc(mmap_object *m_obj) { #ifdef MS_WIN32 - UnmapViewOfFile (m_obj->data); - CloseHandle (m_obj->map_handle); - CloseHandle ((HANDLE)m_obj->file_handle); + if (m_obj->data != NULL) + UnmapViewOfFile (m_obj->data); + if (m_obj->map_handle != INVALID_HANDLE_VALUE) + CloseHandle (m_obj->map_handle); + if ((HANDLE)m_obj->file_handle != INVALID_HANDLE_VALUE) + CloseHandle ((HANDLE)m_obj->file_handle); + if (m_obj->tagname) + PyMem_Free(m_obj->tagname); #endif /* MS_WIN32 */ #ifdef UNIX @@ -826,9 +831,31 @@ new_mmap_object(PyObject *self, PyObject *args) } m_obj = PyObject_New (mmap_object, &mmap_object_type); - + if (m_obj==NULL) + return NULL; + /* Set every field to an invalid marker, so we can safely + destruct the object in the face of failure */ + m_obj->data = NULL; + m_obj->file_handle = (INT_PTR)INVALID_HANDLE_VALUE; + m_obj->map_handle = INVALID_HANDLE_VALUE; + m_obj->tagname = NULL; + if (fh) { - m_obj->file_handle = fh; + /* It is necessary to duplicate the handle, so the + Python code can close it on us */ + if (!DuplicateHandle( + GetCurrentProcess(), /* source process handle */ + (HANDLE)fh, /* handle to be duplicated */ + GetCurrentProcess(), /* target proc handle */ + (LPHANDLE)&m_obj->file_handle, /* result */ + 0, /* access - ignored due to options value */ + FALSE, /* inherited by child processes? */ + DUPLICATE_SAME_ACCESS)) { /* options */ + dwErr = GetLastError(); + Py_DECREF(m_obj); + PyErr_SetFromWindowsErr(dwErr); + return NULL; + } if (!map_size) { m_obj->size = GetFileSize ((HANDLE)fh, NULL); } else { @@ -836,13 +863,25 @@ new_mmap_object(PyObject *self, PyObject *args) } } else { - m_obj->file_handle = (INT_PTR) -1; m_obj->size = map_size; } /* set the initial position */ m_obj->pos = (size_t) 0; + /* set the tag name */ + if (tagname != NULL) { + m_obj->tagname = PyMem_Malloc(strlen(tagname)+1); + if (m_obj->tagname == NULL) { + PyErr_NoMemory(); + Py_DECREF(m_obj); + return NULL; + } + strcpy(m_obj->tagname, tagname); + } + else + m_obj->tagname = NULL; + m_obj->map_handle = CreateFileMapping ((HANDLE) m_obj->file_handle, NULL, PAGE_READWRITE, @@ -863,6 +902,7 @@ new_mmap_object(PyObject *self, PyObject *args) } else { dwErr = GetLastError(); } + Py_DECREF(m_obj); PyErr_SetFromWindowsErr(dwErr); return (NULL); } |