mirror of https://github.com/python/cpython
Patch #412229: Add functions sys.getdlopenflags and sys.setdlopenflags.
Add dlopenflags to PyInterpreterState, and use it in dlopen calls.
This commit is contained in:
parent
984158d25b
commit
f0473d511b
|
@ -180,6 +180,13 @@ way to exit a program when an error occurs.
|
||||||
\versionadded{2.0}
|
\versionadded{2.0}
|
||||||
\end{funcdesc}
|
\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}
|
\begin{funcdesc}{getrefcount}{object}
|
||||||
Return the reference count of the \var{object}. The count returned is
|
Return the reference count of the \var{object}. The count returned is
|
||||||
generally one higher than you might expect, because it includes the
|
generally one higher than you might expect, because it includes the
|
||||||
|
@ -333,6 +340,20 @@ maximizing responsiveness as well as overhead.
|
||||||
\versionadded{2.0}
|
\versionadded{2.0}
|
||||||
\end{funcdesc}
|
\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}
|
\begin{funcdesc}{setprofile}{profilefunc}
|
||||||
Set the system's profile function, which allows you to implement a
|
Set the system's profile function, which allows you to implement a
|
||||||
Python source code profiler in Python. See the chapter on the
|
Python source code profiler in Python. See the chapter on the
|
||||||
|
|
|
@ -23,6 +23,9 @@ typedef struct _is {
|
||||||
PyObject *builtins;
|
PyObject *builtins;
|
||||||
|
|
||||||
int checkinterval;
|
int checkinterval;
|
||||||
|
#ifdef HAVE_DLOPEN
|
||||||
|
int dlopenflags;
|
||||||
|
#endif
|
||||||
|
|
||||||
} PyInterpreterState;
|
} PyInterpreterState;
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,9 @@ Core
|
||||||
|
|
||||||
Library
|
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
|
- Fredrik Lundh's xmlrpclib is now a standard library module. This
|
||||||
provides full client-side XML-RPC support. In addition,
|
provides full client-side XML-RPC support. In addition,
|
||||||
Demo/xmlrpc/ contains two server frameworks (one SocketServer-based,
|
Demo/xmlrpc/ contains two server frameworks (one SocketServer-based,
|
||||||
|
|
|
@ -22,10 +22,6 @@
|
||||||
#define LEAD_UNDERSCORE ""
|
#define LEAD_UNDERSCORE ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RTLD_LAZY
|
|
||||||
#define RTLD_LAZY 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
|
@ -53,6 +49,7 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||||
void *handle;
|
void *handle;
|
||||||
char funcname[258];
|
char funcname[258];
|
||||||
char pathbuf[260];
|
char pathbuf[260];
|
||||||
|
int dlopenflags=0;
|
||||||
|
|
||||||
if (strchr(pathname, '/') == NULL) {
|
if (strchr(pathname, '/') == NULL) {
|
||||||
/* Prefix bare filename with "./" */
|
/* Prefix bare filename with "./" */
|
||||||
|
@ -80,16 +77,13 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RTLD_NOW
|
dlopenflags = PyThreadState_Get()->interp->dlopenflags;
|
||||||
/* RTLD_NOW: resolve externals now
|
|
||||||
(i.e. core dump now if some are missing) */
|
|
||||||
handle = dlopen(pathname, RTLD_NOW);
|
|
||||||
#else
|
|
||||||
if (Py_VerboseFlag)
|
if (Py_VerboseFlag)
|
||||||
printf("dlopen(\"%s\", %d);\n", pathname,
|
printf("dlopen(\"%s\", %x);\n", pathname, dlopenflags);
|
||||||
RTLD_LAZY);
|
|
||||||
handle = dlopen(pathname, RTLD_LAZY);
|
handle = dlopen(pathname, dlopenflags);
|
||||||
#endif /* RTLD_NOW */
|
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
PyErr_SetString(PyExc_ImportError, dlerror());
|
PyErr_SetString(PyExc_ImportError, dlerror());
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -3,6 +3,16 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#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) { \
|
#define ZAP(x) { \
|
||||||
PyObject *tmp = (PyObject *)(x); \
|
PyObject *tmp = (PyObject *)(x); \
|
||||||
(x) = NULL; \
|
(x) = NULL; \
|
||||||
|
@ -39,6 +49,13 @@ PyInterpreterState_New(void)
|
||||||
interp->builtins = NULL;
|
interp->builtins = NULL;
|
||||||
interp->checkinterval = 10;
|
interp->checkinterval = 10;
|
||||||
interp->tstate_head = NULL;
|
interp->tstate_head = NULL;
|
||||||
|
#ifdef HAVE_DLOPEN
|
||||||
|
#ifdef RTLD_NOW
|
||||||
|
interp->dlopenflags = RTLD_NOW;
|
||||||
|
#else
|
||||||
|
interp->dlopenflags = RTLD_LAZY;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
HEAD_LOCK();
|
HEAD_LOCK();
|
||||||
interp->next = interp_head;
|
interp->next = interp_head;
|
||||||
|
|
|
@ -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\
|
of the Python interpreter stack. This limit prevents infinite\n\
|
||||||
recursion from causing an overflow of the C stack and crashing Python.";
|
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
|
#ifdef USE_MALLOPT
|
||||||
/* Link with -lmalloc (or -lmpc) on an SGI */
|
/* Link with -lmalloc (or -lmpc) on an SGI */
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
@ -501,6 +543,10 @@ static PyMethodDef sys_methods[] = {
|
||||||
{"exit", sys_exit, 0, exit_doc},
|
{"exit", sys_exit, 0, exit_doc},
|
||||||
{"getdefaultencoding", sys_getdefaultencoding, 1,
|
{"getdefaultencoding", sys_getdefaultencoding, 1,
|
||||||
getdefaultencoding_doc},
|
getdefaultencoding_doc},
|
||||||
|
#ifdef HAVE_DLOPEN
|
||||||
|
{"getdlopenflags", sys_getdlopenflags, 1,
|
||||||
|
getdlopenflags_doc},
|
||||||
|
#endif
|
||||||
#ifdef COUNT_ALLOCS
|
#ifdef COUNT_ALLOCS
|
||||||
{"getcounts", sys_getcounts, 1},
|
{"getcounts", sys_getcounts, 1},
|
||||||
#endif
|
#endif
|
||||||
|
@ -522,6 +568,10 @@ static PyMethodDef sys_methods[] = {
|
||||||
setdefaultencoding_doc},
|
setdefaultencoding_doc},
|
||||||
{"setcheckinterval", sys_setcheckinterval, 1,
|
{"setcheckinterval", sys_setcheckinterval, 1,
|
||||||
setcheckinterval_doc},
|
setcheckinterval_doc},
|
||||||
|
#ifdef HAVE_DLOPEN
|
||||||
|
{"setdlopenflags", sys_setdlopenflags, 1,
|
||||||
|
setdlopenflags_doc},
|
||||||
|
#endif
|
||||||
{"setprofile", sys_setprofile, 0, setprofile_doc},
|
{"setprofile", sys_setprofile, 0, setprofile_doc},
|
||||||
{"setrecursionlimit", sys_setrecursionlimit, 1,
|
{"setrecursionlimit", sys_setrecursionlimit, 1,
|
||||||
setrecursionlimit_doc},
|
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\
|
excepthook() -- print an exception and its traceback to sys.stderr\n\
|
||||||
exc_info() -- return thread-safe information about the current exception\n\
|
exc_info() -- return thread-safe information about the current exception\n\
|
||||||
exit() -- exit the interpreter by raising SystemExit\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\
|
getrefcount() -- return the reference count for an object (plus one :-)\n\
|
||||||
getrecursionlimit() -- return the max recursion depth for the interpreter\n\
|
getrecursionlimit() -- return the max recursion depth for the interpreter\n\
|
||||||
setcheckinterval() -- control how often the interpreter checks for events\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\
|
setprofile() -- set the global profiling function\n\
|
||||||
setrecursionlimit() -- set the max recursion depth for the interpreter\n\
|
setrecursionlimit() -- set the max recursion depth for the interpreter\n\
|
||||||
settrace() -- set the global debug tracing function\n\
|
settrace() -- set the global debug tracing function\n\
|
||||||
|
|
Loading…
Reference in New Issue