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:
Tim Peters 2004-10-11 02:40:51 +00:00
parent 89c0ec9beb
commit 7f468f29f4
7 changed files with 24 additions and 10 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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();

View File

@ -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