diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-12-06 17:12:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-06 17:12:59 (GMT) |
commit | 92a3c6f493ad411e4cf0acdf305ef4876aa90669 (patch) | |
tree | 67cae429f766b6f99a69a303cf3960dd7893859f /Python | |
parent | 1b4587a2462fc05a14be87123083322103a1f55b (diff) | |
download | cpython-92a3c6f493ad411e4cf0acdf305ef4876aa90669.zip cpython-92a3c6f493ad411e4cf0acdf305ef4876aa90669.tar.gz cpython-92a3c6f493ad411e4cf0acdf305ef4876aa90669.tar.bz2 |
bpo-32030: Add _PyImport_Fini2() (#4737)
PyImport_ExtendInittab() now uses PyMem_RawRealloc() rather than
PyMem_Realloc(). PyImport_ExtendInittab() can be called before
Py_Initialize() whereas only the PyMem_Raw allocator is supposed to
be used before Py_Initialize().
Add _PyImport_Fini2() to release the memory allocated by
PyImport_ExtendInittab() at exit. PyImport_ExtendInittab() now forces
the usage of the default raw allocator, to be able to release memory
in _PyImport_Fini2().
Don't export these functions anymore to be C API, only to
Py_BUILD_CORE:
* _PyExc_Fini()
* _PyImport_Fini()
* _PyGC_DumpShutdownStats()
* _PyGC_Fini()
* _PyType_Fini()
* _Py_HashRandomization_Fini()
Diffstat (limited to 'Python')
-rw-r--r-- | Python/import.c | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/Python/import.c b/Python/import.c index 9a98573..cc7417b 100644 --- a/Python/import.c +++ b/Python/import.c @@ -30,6 +30,7 @@ static PyObject *extensions = NULL; extern struct _inittab _PyImport_Inittab[]; struct _inittab *PyImport_Inittab = _PyImport_Inittab; +static struct _inittab *inittab_copy = NULL; /*[clinic input] module _imp @@ -285,6 +286,19 @@ _PyImport_Fini(void) } } +void +_PyImport_Fini2(void) +{ + /* Use the same memory allocator than PyImport_ExtendInittab(). */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + /* Free memory allocated by PyImport_ExtendInittab() */ + PyMem_RawFree(inittab_copy); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); +} + /* Helper for sys */ PyObject * @@ -2233,9 +2247,9 @@ PyInit_imp(void) int PyImport_ExtendInittab(struct _inittab *newtab) { - static struct _inittab *our_copy = NULL; struct _inittab *p; - int i, n; + Py_ssize_t i, n; + int res = 0; /* Count the number of entries in both tables */ for (n = 0; newtab[n].name != NULL; n++) @@ -2245,19 +2259,35 @@ PyImport_ExtendInittab(struct _inittab *newtab) for (i = 0; PyImport_Inittab[i].name != NULL; i++) ; + /* Force default raw memory allocator to get a known allocator to be able + to release the memory in _PyImport_Fini2() */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + /* Allocate new memory for the combined table */ - p = our_copy; - PyMem_RESIZE(p, struct _inittab, i+n+1); - if (p == NULL) - return -1; + if ((i + n + 1) <= PY_SSIZE_T_MAX / sizeof(struct _inittab)) { + size_t size = sizeof(struct _inittab) * (i + n + 1); + p = PyMem_RawRealloc(inittab_copy, size); + } + else { + p = NULL; + } + if (p == NULL) { + res = -1; + goto done; + } - /* Copy the tables into the new memory */ - if (our_copy != PyImport_Inittab) + /* Copy the tables into the new memory at the first call + to PyImport_ExtendInittab(). */ + if (inittab_copy != PyImport_Inittab) { memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab)); - PyImport_Inittab = our_copy = p; - memcpy(p+i, newtab, (n+1) * sizeof(struct _inittab)); + } + memcpy(p + i, newtab, (n + 1) * sizeof(struct _inittab)); + PyImport_Inittab = inittab_copy = p; - return 0; +done: + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return res; } /* Shorthand to add a single entry given a name and a function */ |