diff options
-rw-r--r-- | Doc/lib/libsys.tex | 21 | ||||
-rw-r--r-- | Include/pystate.h | 3 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Python/dynload_shlib.c | 20 | ||||
-rw-r--r-- | Python/pystate.c | 17 | ||||
-rw-r--r-- | Python/sysmodule.c | 52 |
6 files changed, 103 insertions, 13 deletions
diff --git a/Doc/lib/libsys.tex b/Doc/lib/libsys.tex index be5a599..4818cfd 100644 --- a/Doc/lib/libsys.tex +++ b/Doc/lib/libsys.tex @@ -180,6 +180,13 @@ way to exit a program when an error occurs. \versionadded{2.0} \end{funcdesc} +\begin{funcdesc}{getdlopenflags}{} + Return the current value of the flags that are used for \code{dlopen} + calls. The flag constants are defined in the \refmodule{dl} and + \module{DLFCN} modules. + \versionadded{2.2} +\end{funcdesc} + \begin{funcdesc}{getrefcount}{object} Return the reference count of the \var{object}. The count returned is generally one higher than you might expect, because it includes the @@ -333,6 +340,20 @@ maximizing responsiveness as well as overhead. \versionadded{2.0} \end{funcdesc} +\begin{funcdesc}{sertdlopenflags}{n} + Set the flags that will be used for \code{dlopen()} calls, i.e. when + the interpreter loads extension modules. Among other things, this + will enable a lazy resolving of symbols when imporing a module, if + called as \code{sys.setdlopenflags(0)}. To share symols across + extension modules, call as + \code{sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)}. The symbolic + names for the flag modules can be either found in the \refmodule{dl} + module, or in the \module{DLFCN} module. If \module{DLFCN} is not + available, it can be generated from \code{/usr/include/dlfcn.h} using + the \code{h2py} script. + \versionadded{2.2} +\end{funcdesc} + \begin{funcdesc}{setprofile}{profilefunc} Set the system's profile function, which allows you to implement a Python source code profiler in Python. See the chapter on the diff --git a/Include/pystate.h b/Include/pystate.h index 15a264c..41024e8 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -23,6 +23,9 @@ typedef struct _is { PyObject *builtins; int checkinterval; +#ifdef HAVE_DLOPEN + int dlopenflags; +#endif } PyInterpreterState; @@ -149,6 +149,9 @@ Core Library +- The flags used in dlopen calls can now be configured using + sys.setdlopenflags and queried using sys.getdlopenflags. + - Fredrik Lundh's xmlrpclib is now a standard library module. This provides full client-side XML-RPC support. In addition, Demo/xmlrpc/ contains two server frameworks (one SocketServer-based, diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index 7c8bfd2..7de3b7d 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -22,10 +22,6 @@ #define LEAD_UNDERSCORE "" #endif -#ifndef RTLD_LAZY -#define RTLD_LAZY 1 -#endif - const struct filedescr _PyImport_DynLoadFiletab[] = { #ifdef __CYGWIN__ @@ -53,6 +49,7 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, void *handle; char funcname[258]; char pathbuf[260]; + int dlopenflags=0; if (strchr(pathname, '/') == NULL) { /* Prefix bare filename with "./" */ @@ -80,16 +77,13 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, } } -#ifdef RTLD_NOW - /* RTLD_NOW: resolve externals now - (i.e. core dump now if some are missing) */ - handle = dlopen(pathname, RTLD_NOW); -#else + dlopenflags = PyThreadState_Get()->interp->dlopenflags; + if (Py_VerboseFlag) - printf("dlopen(\"%s\", %d);\n", pathname, - RTLD_LAZY); - handle = dlopen(pathname, RTLD_LAZY); -#endif /* RTLD_NOW */ + printf("dlopen(\"%s\", %x);\n", pathname, dlopenflags); + + handle = dlopen(pathname, dlopenflags); + if (handle == NULL) { PyErr_SetString(PyExc_ImportError, dlerror()); return NULL; diff --git a/Python/pystate.c b/Python/pystate.c index cca1e7c..2f15fdf 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,6 +3,16 @@ #include "Python.h" +#ifdef HAVE_DLOPEN +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> +#endif +#ifndef RTLD_LAZY +#define RTLD_LAZY 1 +#endif +#endif + + #define ZAP(x) { \ PyObject *tmp = (PyObject *)(x); \ (x) = NULL; \ @@ -39,6 +49,13 @@ PyInterpreterState_New(void) interp->builtins = NULL; interp->checkinterval = 10; interp->tstate_head = NULL; +#ifdef HAVE_DLOPEN +#ifdef RTLD_NOW + interp->dlopenflags = RTLD_NOW; +#else + interp->dlopenflags = RTLD_LAZY; +#endif +#endif HEAD_LOCK(); interp->next = interp_head; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 76d40bf..0d6d5a0 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -394,6 +394,48 @@ Return the current value of the recursion limit, the maximum depth\n\ of the Python interpreter stack. This limit prevents infinite\n\ recursion from causing an overflow of the C stack and crashing Python."; +#ifdef HAVE_DLOPEN +static PyObject * +sys_setdlopenflags(PyObject *self, PyObject *args) +{ + int new_val; + PyThreadState *tstate = PyThreadState_Get(); + if (!PyArg_ParseTuple(args, "i:setdlopenflags", &new_val)) + return NULL; + if (!tstate) + return NULL; + tstate->interp->dlopenflags = new_val; + Py_INCREF(Py_None); + return Py_None; +} + +static char setdlopenflags_doc[] = +"setdlopenflags(n) -> None\n\ +\n\ +Set the flags that will be used for dlopen() calls. Among other\n\ +things, this will enable a lazy resolving of symbols when imporing\n\ +a module, if called as sys.setdlopenflags(0)\n\ +To share symols across extension modules, call as\n\ +sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)"; + +static PyObject * +sys_getdlopenflags(PyObject *self, PyObject *args) +{ + PyThreadState *tstate = PyThreadState_Get(); + if (!PyArg_ParseTuple(args, ":getdlopenflags")) + return NULL; + if (!tstate) + return NULL; + return PyInt_FromLong(tstate->interp->dlopenflags); +} + +static char getdlopenflags_doc[] = +"getdlopenflags() -> int\n\ +\n\ +Return the current value of the flags that are used for dlopen()\n\ +calls. The flag constants are defined in the dl module."; +#endif + #ifdef USE_MALLOPT /* Link with -lmalloc (or -lmpc) on an SGI */ #include <malloc.h> @@ -501,6 +543,10 @@ static PyMethodDef sys_methods[] = { {"exit", sys_exit, 0, exit_doc}, {"getdefaultencoding", sys_getdefaultencoding, 1, getdefaultencoding_doc}, +#ifdef HAVE_DLOPEN + {"getdlopenflags", sys_getdlopenflags, 1, + getdlopenflags_doc}, +#endif #ifdef COUNT_ALLOCS {"getcounts", sys_getcounts, 1}, #endif @@ -522,6 +568,10 @@ static PyMethodDef sys_methods[] = { setdefaultencoding_doc}, {"setcheckinterval", sys_setcheckinterval, 1, setcheckinterval_doc}, +#ifdef HAVE_DLOPEN + {"setdlopenflags", sys_setdlopenflags, 1, + setdlopenflags_doc}, +#endif {"setprofile", sys_setprofile, 0, setprofile_doc}, {"setrecursionlimit", sys_setrecursionlimit, 1, setrecursionlimit_doc}, @@ -659,9 +709,11 @@ displayhook() -- print an object to the screen, and save it in __builtin__._\n\ excepthook() -- print an exception and its traceback to sys.stderr\n\ exc_info() -- return thread-safe information about the current exception\n\ exit() -- exit the interpreter by raising SystemExit\n\ +getdlopenflags() -- returns flags to be used for dlopen() calls\n\ getrefcount() -- return the reference count for an object (plus one :-)\n\ getrecursionlimit() -- return the max recursion depth for the interpreter\n\ setcheckinterval() -- control how often the interpreter checks for events\n\ +setdlopenflags() -- set the flags to be used for dlopen() calls\n\ setprofile() -- set the global profiling function\n\ setrecursionlimit() -- set the max recursion depth for the interpreter\n\ settrace() -- set the global debug tracing function\n\ |