From 51d19cf22798a34285eb78426eb349354fca4320 Mon Sep 17 00:00:00 2001 From: Thomas Heller Date: Sun, 8 Aug 2010 18:24:06 +0000 Subject: Merged revisions 83837,83841 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r83837 | thomas.heller | 2010-08-08 19:58:53 +0200 (So, 08 Aug 2010) | 3 lines Fix issue5504: ctypes does now work with systems where mmap can't be PROT_WRITE and PROT_EXEC. ........ r83841 | thomas.heller | 2010-08-08 20:16:20 +0200 (So, 08 Aug 2010) | 2 lines Fix issue6869: refcount problem in the _ctypes extension. ........ --- Misc/NEWS | 5 +++++ Modules/_ctypes/_ctypes.c | 8 +++++++- Modules/_ctypes/callbacks.c | 16 ++++++++++------ Modules/_ctypes/ctypes.h | 3 ++- Modules/_ctypes/libffi/fficonfig.py.in | 2 ++ Modules/_ctypes/libffi_msvc/ffi.c | 10 +++++----- Modules/_ctypes/libffi_msvc/ffi.h | 8 ++++++-- Modules/_ctypes/malloc_closure.c | 8 +++++--- setup.py | 3 +-- 9 files changed, 43 insertions(+), 20 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 42d0d37..5670f0d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,11 @@ What's New in Python 3.1.3? Core and Builtins ----------------- +- Issue #6869: Fix a refcount problem in the _ctypes extension. + +- Issue #5504: ctypes should now work with systems where mmap can't + be PROT_WRITE and PROT_EXEC. + - Issue #8814: function annotations (the ``__annotations__`` attribute) are now included in the set of attributes copied by default by functools.wraps and functools.update_wrapper. Patch by Terrence Cole. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index c1b3093..3d53a47 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -3367,7 +3367,7 @@ PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->callable = callable; self->thunk = thunk; - *(void **)self->b_ptr = (void *)thunk->pcl; + *(void **)self->b_ptr = (void *)thunk->pcl_exec; Py_INCREF((PyObject *)thunk); /* for KeepRef */ if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) { @@ -5326,36 +5326,42 @@ PyInit__ctypes(void) Struct_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Struct_Type) < 0) return NULL; + Py_INCREF(&Struct_Type); PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type); Py_TYPE(&Union_Type) = &UnionType_Type; Union_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Union_Type) < 0) return NULL; + Py_INCREF(&Union_Type); PyModule_AddObject(m, "Union", (PyObject *)&Union_Type); Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type; PyCPointer_Type.tp_base = &PyCData_Type; if (PyType_Ready(&PyCPointer_Type) < 0) return NULL; + Py_INCREF(&PyCPointer_Type); PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type); Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type; PyCArray_Type.tp_base = &PyCData_Type; if (PyType_Ready(&PyCArray_Type) < 0) return NULL; + Py_INCREF(&PyCArray_Type); PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type); Py_TYPE(&Simple_Type) = &PyCSimpleType_Type; Simple_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Simple_Type) < 0) return NULL; + Py_INCREF(&Simple_Type); PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type); Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type; PyCFuncPtr_Type.tp_base = &PyCData_Type; if (PyType_Ready(&PyCFuncPtr_Type) < 0) return NULL; + Py_INCREF(&PyCFuncPtr_Type); PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type); /************************************************* diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 5c82f77..dd19d80 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -16,8 +16,8 @@ CThunkObject_dealloc(PyObject *_self) Py_XDECREF(self->converters); Py_XDECREF(self->callable); Py_XDECREF(self->restype); - if (self->pcl) - _ctypes_free_closure(self->pcl); + if (self->pcl_write) + ffi_closure_free(self->pcl_write); PyObject_GC_Del(self); } @@ -370,7 +370,8 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs) return NULL; } - p->pcl = NULL; + p->pcl_exec = NULL; + p->pcl_write = NULL; memset(&p->cif, 0, sizeof(p->cif)); p->converters = NULL; p->callable = NULL; @@ -400,8 +401,9 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, assert(CThunk_CheckExact((PyObject *)p)); - p->pcl = _ctypes_alloc_closure(); - if (p->pcl == NULL) { + p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure), + &p->pcl_exec); + if (p->pcl_write == NULL) { PyErr_NoMemory(); goto error; } @@ -446,7 +448,9 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, "ffi_prep_cif failed with %d", result); goto error; } - result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p); + result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn, + p, + p->pcl_exec); if (result != FFI_OK) { PyErr_Format(PyExc_RuntimeError, "ffi_prep_closure failed with %d", result); diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 0af5fa1..27abe65 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -58,7 +58,8 @@ struct tagCDataObject { typedef struct { PyObject_VAR_HEAD - ffi_closure *pcl; /* the C callable */ + ffi_closure *pcl_write; /* the C callable, writeable */ + void *pcl_exec; /* the C callable, executable */ ffi_cif cif; int flags; PyObject *converters; diff --git a/Modules/_ctypes/libffi/fficonfig.py.in b/Modules/_ctypes/libffi/fficonfig.py.in index 1029327..775c9e3 100644 --- a/Modules/_ctypes/libffi/fficonfig.py.in +++ b/Modules/_ctypes/libffi/fficonfig.py.in @@ -1,5 +1,7 @@ ffi_sources = """ src/prep_cif.c +src/closures.c +src/dlmalloc.c """.split() ffi_platforms = { diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c index 763d179..65581a7 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.c +++ b/Modules/_ctypes/libffi_msvc/ffi.c @@ -371,10 +371,11 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, extern void ffi_closure_OUTER(); ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) { short bytes; char *tramp; @@ -452,6 +453,5 @@ ffi_prep_closure (ffi_closure* closure, closure->cif = cif; closure->user_data = user_data; closure->fun = fun; - return FFI_OK; } diff --git a/Modules/_ctypes/libffi_msvc/ffi.h b/Modules/_ctypes/libffi_msvc/ffi.h index a88d874..efb14c5 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.h +++ b/Modules/_ctypes/libffi_msvc/ffi.h @@ -221,11 +221,15 @@ typedef struct { void *user_data; } ffi_closure; +void ffi_closure_free(void *); +void *ffi_closure_alloc (size_t size, void **code); + ffi_status -ffi_prep_closure (ffi_closure*, +ffi_prep_closure_loc (ffi_closure*, ffi_cif *, void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data); + void *user_data, + void *codeloc); typedef struct { char tramp[FFI_TRAMPOLINE_SIZE]; diff --git a/Modules/_ctypes/malloc_closure.c b/Modules/_ctypes/malloc_closure.c index ae857a2..519941b 100644 --- a/Modules/_ctypes/malloc_closure.c +++ b/Modules/_ctypes/malloc_closure.c @@ -89,7 +89,7 @@ static void more_core(void) /******************************************************************/ /* put the item back into the free list */ -void _ctypes_free_closure(void *p) +void ffi_closure_free(void *p) { ITEM *item = (ITEM *)p; item->next = free_list; @@ -97,7 +97,7 @@ void _ctypes_free_closure(void *p) } /* return one item from the free list, allocating more if needed */ -void *_ctypes_alloc_closure(void) +void *ffi_closure_alloc(size_t ignored, void** codeloc) { ITEM *item; if (!free_list) @@ -106,5 +106,7 @@ void *_ctypes_alloc_closure(void) return NULL; item = free_list; free_list = item->next; - return item; + *codeloc = (void *)item; + return (void *)item; } + diff --git a/setup.py b/setup.py index 332033d..3cfd275 100644 --- a/setup.py +++ b/setup.py @@ -1636,8 +1636,7 @@ class PyBuildExt(build_ext): '_ctypes/callbacks.c', '_ctypes/callproc.c', '_ctypes/stgdict.c', - '_ctypes/cfield.c', - '_ctypes/malloc_closure.c'] + '_ctypes/cfield.c'] depends = ['_ctypes/ctypes.h'] if sys.platform == 'darwin': -- cgit v0.12