Add a new function imp.lock_held(), and use it to skip test_threaded_import
when that test is doomed to deadlock.
This commit is contained in:
parent
c41418751f
commit
692323488b
|
@ -93,6 +93,19 @@ Return a new empty module object called \var{name}. This object is
|
||||||
\emph{not} inserted in \code{sys.modules}.
|
\emph{not} inserted in \code{sys.modules}.
|
||||||
\end{funcdesc}
|
\end{funcdesc}
|
||||||
|
|
||||||
|
\begin{funcdesc}{lock_held}{}
|
||||||
|
Return 1 if the import lock is currently held, else 0.
|
||||||
|
On platforms without threads, always return 0.
|
||||||
|
|
||||||
|
On platforms with threads, a thread executing an import holds an internal
|
||||||
|
lock until the import is complete.
|
||||||
|
This lock blocks other threads from doing an import until the original
|
||||||
|
import completes, which in turn prevents other threads from seeing
|
||||||
|
incomplete module objects constructed by the original thread while in
|
||||||
|
the process of completing its import (and the imports, if any,
|
||||||
|
triggered by that).
|
||||||
|
\end{funcdesc}
|
||||||
|
|
||||||
The following constants with integer values, defined in this module,
|
The following constants with integer values, defined in this module,
|
||||||
are used to indicate the search result of \function{find_module()}.
|
are used to indicate the search result of \function{find_module()}.
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,12 @@ def task():
|
||||||
|
|
||||||
def test_main(): # magic name! see above
|
def test_main(): # magic name! see above
|
||||||
global N, done
|
global N, done
|
||||||
import sys
|
|
||||||
for modname in sys.modules:
|
import imp
|
||||||
if modname.find('autotest') >= 0:
|
if imp.lock_held():
|
||||||
raise TestSkipped("can't run from autotest")
|
# This triggers on, e.g., from test import autotest.
|
||||||
|
raise TestSkipped("can't run when import lock is held")
|
||||||
|
|
||||||
done.acquire()
|
done.acquire()
|
||||||
for N in (20, 50) * 3:
|
for N in (20, 50) * 3:
|
||||||
if verbose:
|
if verbose:
|
||||||
|
|
|
@ -8,6 +8,9 @@ Core
|
||||||
|
|
||||||
Library
|
Library
|
||||||
|
|
||||||
|
+ A new function, imp.lock_held(), returns 1 when the import lock is
|
||||||
|
currently held. See the docs for the imp module.
|
||||||
|
|
||||||
+ pickle, cPickle and marshal on 32-bit platforms can now correctly read
|
+ pickle, cPickle and marshal on 32-bit platforms can now correctly read
|
||||||
dumps containing ints written on platforms where Python ints are 8 bytes.
|
dumps containing ints written on platforms where Python ints are 8 bytes.
|
||||||
When read on a box where Python ints are 4 bytes, such values are
|
When read on a box where Python ints are 4 bytes, such values are
|
||||||
|
@ -17,6 +20,12 @@ Tools
|
||||||
|
|
||||||
Build
|
Build
|
||||||
|
|
||||||
|
API
|
||||||
|
|
||||||
|
+ XXX Say something about Neil's GC rework, and that extensions that
|
||||||
|
don't upgrade to the new scheme will still compile but not actually
|
||||||
|
participate in GC.
|
||||||
|
|
||||||
New platforms
|
New platforms
|
||||||
|
|
||||||
Tests
|
Tests
|
||||||
|
|
|
@ -181,6 +181,18 @@ unlock_import(void)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
imp_lock_held(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
if (!PyArg_ParseTuple(args, ":lock_held"))
|
||||||
|
return NULL;
|
||||||
|
#ifdef WITH_THREAD
|
||||||
|
return PyInt_FromLong(import_lock_thread != -1);
|
||||||
|
#else
|
||||||
|
return PyInt_FromLong(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Helper for sys */
|
/* Helper for sys */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
|
@ -2339,12 +2351,19 @@ Create a new module. Do not enter it in sys.modules.\n\
|
||||||
The module name must include the full package name, if any.\
|
The module name must include the full package name, if any.\
|
||||||
";
|
";
|
||||||
|
|
||||||
|
static char doc_lock_held[] = "\
|
||||||
|
lock_held() -> 0 or 1\n\
|
||||||
|
Return 1 if the import lock is currently held.\n\
|
||||||
|
On platforms without threads, return 0.\
|
||||||
|
";
|
||||||
|
|
||||||
static PyMethodDef imp_methods[] = {
|
static PyMethodDef imp_methods[] = {
|
||||||
{"find_module", imp_find_module, 1, doc_find_module},
|
{"find_module", imp_find_module, 1, doc_find_module},
|
||||||
{"get_magic", imp_get_magic, 1, doc_get_magic},
|
{"get_magic", imp_get_magic, 1, doc_get_magic},
|
||||||
{"get_suffixes", imp_get_suffixes, 1, doc_get_suffixes},
|
{"get_suffixes", imp_get_suffixes, 1, doc_get_suffixes},
|
||||||
{"load_module", imp_load_module, 1, doc_load_module},
|
{"load_module", imp_load_module, 1, doc_load_module},
|
||||||
{"new_module", imp_new_module, 1, doc_new_module},
|
{"new_module", imp_new_module, 1, doc_new_module},
|
||||||
|
{"lock_held", imp_lock_held, 1, doc_lock_held},
|
||||||
/* The rest are obsolete */
|
/* The rest are obsolete */
|
||||||
{"get_frozen_object", imp_get_frozen_object, 1},
|
{"get_frozen_object", imp_get_frozen_object, 1},
|
||||||
{"init_builtin", imp_init_builtin, 1},
|
{"init_builtin", imp_init_builtin, 1},
|
||||||
|
|
Loading…
Reference in New Issue