diff -r e55f955659bc Python/dynload_shlib.c --- a/Python/dynload_shlib.c Fri Feb 06 08:56:33 2015 +0200 +++ b/Python/dynload_shlib.c Fri Feb 06 13:06:34 2015 -0500 @@ -54,7 +54,7 @@ {0, 0} }; -static struct { +static struct dynload_handle { dev_t dev; #ifdef __VMS ino_t ino[3]; @@ -62,9 +62,20 @@ ino_t ino; #endif void *handle; -} handles[128]; -static int nhandles = 0; + struct dynload_handle *next; +} *handles; +static void dynload_unload_all(void) +{ + struct dynload_handle *dhandle = handles; + while (dhandle != NULL) { + struct dynload_handle *next = dhandle->next; + dlclose(dhandle->handle); + free(dhandle); + dhandle = next; + } + handles = NULL; +} dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, const char *pathname, FILE *fp) @@ -74,6 +85,9 @@ char funcname[258]; char pathbuf[260]; int dlopenflags=0; + static int init; + struct stat statb; + struct dynload_handle *dhandle; if (strchr(pathname, '/') == NULL) { /* Prefix bare filename with "./" */ @@ -85,27 +99,15 @@ LEAD_UNDERSCORE "init%.200s", shortname); if (fp != NULL) { - int i; - struct stat statb; fstat(fileno(fp), &statb); - for (i = 0; i < nhandles; i++) { - if (statb.st_dev == handles[i].dev && - statb.st_ino == handles[i].ino) { - p = (dl_funcptr) dlsym(handles[i].handle, + for (dhandle = handles; dhandle; dhandle = dhandle->next) { + if (statb.st_dev == dhandle->dev && + statb.st_ino == dhandle->ino) { + p = (dl_funcptr) dlsym(dhandle->handle, funcname); return p; } } - if (nhandles < 128) { - handles[nhandles].dev = statb.st_dev; -#ifdef __VMS - handles[nhandles].ino[0] = statb.st_ino[0]; - handles[nhandles].ino[1] = statb.st_ino[1]; - handles[nhandles].ino[2] = statb.st_ino[2]; -#else - handles[nhandles].ino = statb.st_ino; -#endif - } } #if !(defined(PYOS_OS2) && defined(PYCC_GCC)) @@ -136,8 +138,29 @@ PyErr_SetString(PyExc_ImportError, error); return NULL; } - if (fp != NULL && nhandles < 128) - handles[nhandles++].handle = handle; + + if (!init) { + init = 1; + Py_AtExit(dynload_unload_all); + } + + dhandle = malloc(sizeof(struct dynload_handle)); + if (dhandle != NULL) { + if (fp != NULL) { + dhandle->dev = statb.st_dev; +#ifdef __VMS + dhandle->ino[0] = statb.st_ino[0]; + dhandle->ino[1] = statb.st_ino[1]; + dhandle->ino[2] = statb.st_ino[2]; +#else + dhandle->ino = statb.st_ino; +#endif + } + dhandle->handle = handle; + dhandle->next = handles; + handles = dhandle; + } + p = (dl_funcptr) dlsym(handle, funcname); return p; }