SF patch 1044089: New C API function PyEval_ThreadsInitialized(), by Nick
Coghlan, for determining whether PyEval_InitThreads() has been called. Also purged the undocumented+unused _PyThread_Started int.
This commit is contained in:
parent
89c0ec9beb
commit
7f468f29f4
|
@ -24,7 +24,7 @@
|
||||||
\end{cfuncdesc}
|
\end{cfuncdesc}
|
||||||
|
|
||||||
\begin{cfuncdesc}{void}{Py_InitializeEx}{int initsigs}
|
\begin{cfuncdesc}{void}{Py_InitializeEx}{int initsigs}
|
||||||
This function works like \cfunction{Py_Initialize} if
|
This function works like \cfunction{Py_Initialize()} if
|
||||||
\var{initsigs} is 1. If \var{initsigs} is 0, it skips
|
\var{initsigs} is 1. If \var{initsigs} is 0, it skips
|
||||||
initialization registration of signal handlers, which
|
initialization registration of signal handlers, which
|
||||||
might be useful when Python is embedded. \versionadded{2.4}
|
might be useful when Python is embedded. \versionadded{2.4}
|
||||||
|
@ -517,14 +517,14 @@ for calling into Python from a C thread is
|
||||||
This is a common situation (most Python programs do not use
|
This is a common situation (most Python programs do not use
|
||||||
threads), and the lock operations slow the interpreter down a bit.
|
threads), and the lock operations slow the interpreter down a bit.
|
||||||
Therefore, the lock is not created initially. This situation is
|
Therefore, the lock is not created initially. This situation is
|
||||||
equivalent to having acquired the lock: when there is only a single
|
equivalent to having acquired the lock: when there is only a single
|
||||||
thread, all object accesses are safe. Therefore, when this function
|
thread, all object accesses are safe. Therefore, when this function
|
||||||
initializes the lock, it also acquires it. Before the Python
|
initializes the lock, it also acquires it. Before the Python
|
||||||
\module{thread}\refbimodindex{thread} module creates a new thread,
|
\module{thread}\refbimodindex{thread} module creates a new thread,
|
||||||
knowing that either it has the lock or the lock hasn't been created
|
knowing that either it has the lock or the lock hasn't been created
|
||||||
yet, it calls \cfunction{PyEval_InitThreads()}. When this call
|
yet, it calls \cfunction{PyEval_InitThreads()}. When this call
|
||||||
returns, it is guaranteed that the lock has been created and that it
|
returns, it is guaranteed that the lock has been created and that the
|
||||||
has acquired it.
|
calling thread has acquired it.
|
||||||
|
|
||||||
It is \strong{not} safe to call this function when it is unknown
|
It is \strong{not} safe to call this function when it is unknown
|
||||||
which thread (if any) currently has the global interpreter lock.
|
which thread (if any) currently has the global interpreter lock.
|
||||||
|
@ -533,6 +533,14 @@ for calling into Python from a C thread is
|
||||||
compile time.
|
compile time.
|
||||||
\end{cfuncdesc}
|
\end{cfuncdesc}
|
||||||
|
|
||||||
|
\begin{cfuncdesc}{int}{PyEval_ThreadsInitialized}{}
|
||||||
|
Returns a non-zero value if \cfunction{PyEval_InitThreads()} has been
|
||||||
|
called. This function can be called without holding the lock, and
|
||||||
|
therefore can be used to avoid calls to the locking API when running
|
||||||
|
single-threaded. This function is not available when thread support
|
||||||
|
is disabled at compile time. \versionadded{2.4}
|
||||||
|
\end{cfuncdesc}
|
||||||
|
|
||||||
\begin{cfuncdesc}{void}{PyEval_AcquireLock}{}
|
\begin{cfuncdesc}{void}{PyEval_AcquireLock}{}
|
||||||
Acquire the global interpreter lock. The lock must have been
|
Acquire the global interpreter lock. The lock must have been
|
||||||
created earlier. If this thread already has the lock, a deadlock
|
created earlier. If this thread already has the lock, a deadlock
|
||||||
|
|
|
@ -120,6 +120,7 @@ PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
|
|
||||||
|
PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
|
||||||
PyAPI_FUNC(void) PyEval_InitThreads(void);
|
PyAPI_FUNC(void) PyEval_InitThreads(void);
|
||||||
PyAPI_FUNC(void) PyEval_AcquireLock(void);
|
PyAPI_FUNC(void) PyEval_AcquireLock(void);
|
||||||
PyAPI_FUNC(void) PyEval_ReleaseLock(void);
|
PyAPI_FUNC(void) PyEval_ReleaseLock(void);
|
||||||
|
|
|
@ -136,6 +136,11 @@ Build
|
||||||
C API
|
C API
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
- SF patch 1044089: New function ``PyEval_ThreadsInitialized()`` returns
|
||||||
|
non-zero if PyEval_InitThreads() has been called.
|
||||||
|
|
||||||
|
- The undocumented and unused extern int ``_PyThread_Started`` was removed.
|
||||||
|
|
||||||
- The C API calls ``PyInterpreterState_New()`` and ``PyThreadState_New()``
|
- The C API calls ``PyInterpreterState_New()`` and ``PyThreadState_New()``
|
||||||
are two of the very few advertised as being safe to call without holding
|
are two of the very few advertised as being safe to call without holding
|
||||||
the GIL. However, this wasn't true in a debug build, as bug 1041645
|
the GIL. However, this wasn't true in a debug build, as bug 1041645
|
||||||
|
|
|
@ -980,7 +980,6 @@ EXPORTS
|
||||||
"Py_UseClassExceptionsFlag"
|
"Py_UseClassExceptionsFlag"
|
||||||
"Py_UnicodeFlag"
|
"Py_UnicodeFlag"
|
||||||
"_Py_QnewFlag"
|
"_Py_QnewFlag"
|
||||||
"_PyThread_Started"
|
|
||||||
|
|
||||||
; From python24_s.lib(structmember)
|
; From python24_s.lib(structmember)
|
||||||
"PyMember_Get"
|
"PyMember_Get"
|
||||||
|
|
|
@ -69,7 +69,6 @@ EXPORTS
|
||||||
_PyImport_Inittab
|
_PyImport_Inittab
|
||||||
_PyParser_Grammar
|
_PyParser_Grammar
|
||||||
_PyParser_TokenNames
|
_PyParser_TokenNames
|
||||||
_PyThread_Started
|
|
||||||
_Py_EllipsisObject
|
_Py_EllipsisObject
|
||||||
_Py_NoneStruct
|
_Py_NoneStruct
|
||||||
_Py_PackageContext
|
_Py_PackageContext
|
||||||
|
|
|
@ -203,17 +203,20 @@ PyEval_GetCallStats(PyObject *self)
|
||||||
#endif
|
#endif
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
|
|
||||||
extern int _PyThread_Started; /* Flag for Py_Exit */
|
|
||||||
|
|
||||||
static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */
|
static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */
|
||||||
static long main_thread = 0;
|
static long main_thread = 0;
|
||||||
|
|
||||||
|
int
|
||||||
|
PyEval_ThreadsInitialized(void)
|
||||||
|
{
|
||||||
|
return interpreter_lock != 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PyEval_InitThreads(void)
|
PyEval_InitThreads(void)
|
||||||
{
|
{
|
||||||
if (interpreter_lock)
|
if (interpreter_lock)
|
||||||
return;
|
return;
|
||||||
_PyThread_Started = 1;
|
|
||||||
interpreter_lock = PyThread_allocate_lock();
|
interpreter_lock = PyThread_allocate_lock();
|
||||||
PyThread_acquire_lock(interpreter_lock, 1);
|
PyThread_acquire_lock(interpreter_lock, 1);
|
||||||
main_thread = PyThread_get_thread_ident();
|
main_thread = PyThread_get_thread_ident();
|
||||||
|
|
|
@ -1517,7 +1517,6 @@ Py_FatalError(const char *msg)
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
int _PyThread_Started = 0; /* Set by threadmodule.c and maybe others */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NEXITFUNCS 32
|
#define NEXITFUNCS 32
|
||||||
|
|
Loading…
Reference in New Issue