Make use if the new PyGILState_ API if available.

Not part of the build.


git-svn-id: svn://10.0.0.236/trunk@141465 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mhammond%skippinet.com.au
2003-04-20 02:47:31 +00:00
parent d7f40ef4bd
commit 50caa43aa2
4 changed files with 62 additions and 12 deletions

View File

@@ -555,16 +555,40 @@ public:
// NEVER new one of these objects - only use on the stack!
extern PYXPCOM_EXPORT void PyXPCOM_MakePendingCalls();
extern PYXPCOM_EXPORT PRBool PyXPCOM_Globals_Ensure();
// For 2.3, use the PyGILState_ calls
#if (PY_VERSION_HEX >= 0x02030000)
#define PYXPCOM_USE_PYGILSTATE
#endif
#ifdef PYXPCOM_USE_PYGILSTATE
class CEnterLeavePython {
public:
CEnterLeavePython() {
state = PyGILState_Ensure();
// See "pending calls" comment below. We reach into the Python
// implementation to see if we are the first call on the stack.
if (PyThreadState_Get()->gilstate_counter==1) {
PyXPCOM_MakePendingCalls();
}
}
~CEnterLeavePython() {
PyGILState_Release(state);
}
PyGILState_STATE state;
};
#else
extern PYXPCOM_EXPORT PyInterpreterState *PyXPCOM_InterpreterState;
extern PYXPCOM_EXPORT PRBool PyXPCOM_ThreadState_Ensure();
extern PYXPCOM_EXPORT void PyXPCOM_ThreadState_Free();
extern PYXPCOM_EXPORT void PyXPCOM_ThreadState_Clear();
extern PYXPCOM_EXPORT void PyXPCOM_InterpreterLock_Acquire();
extern PYXPCOM_EXPORT void PyXPCOM_InterpreterLock_Release();
extern PYXPCOM_EXPORT void PyXPCOM_MakePendingCalls();
extern PYXPCOM_EXPORT PRBool PyXPCOM_Globals_Ensure();
// Pre 2.3 thread-state dances.
class CEnterLeavePython {
public:
CEnterLeavePython() {
@@ -602,6 +626,7 @@ public:
private:
PRBool created;
};
#endif // PYXPCOM_USE_PYGILSTATE
// Our classes.
// Hrm - So we can't have templates, eh??

View File

@@ -38,16 +38,18 @@
#endif
static PRInt32 g_cLockCount = 0;
static PyThreadState *ptsGlobal = nsnull;
PyInterpreterState *PyXPCOM_InterpreterState = nsnull;
static PRLock *g_lockMain = nsnull;
PRUintn tlsIndex = 0;
#ifndef PYXPCOM_USE_PYGILSTATE
////////////////////////////////////////////////////////////
// Thread-state helpers/global functions.
// Only used if there is no Python PyGILState_* API
//
static PyThreadState *ptsGlobal = nsnull;
PyInterpreterState *PyXPCOM_InterpreterState = nsnull;
PRUintn tlsIndex = 0;
// This function must be called at some time when the interpreter lock and state is valid.
// Called by init{module} functions and also COM factory entry point.
@@ -139,6 +141,7 @@ void PyXPCOM_ThreadState_Clear()
PyThreadState *thisThreadState = pData->ts;
PyThreadState_Clear(thisThreadState);
}
#endif // PYXPCOM_USE_PYGILSTATE
////////////////////////////////////////////////////////////
// Lock/exclusion global functions.
@@ -177,8 +180,10 @@ void PyXPCOM_DLLAddRef(void)
// Must force Python to start using thread locks, as
// we are free-threaded (maybe, I think, sometimes :-)
PyEval_InitThreads();
#ifndef PYXPCOM_USE_PYGILSTATE
// Release Python lock, as first thing we do is re-get it.
ptsGlobal = PyEval_SaveThread();
#endif
// NOTE: We never finalize Python!!
}
}
@@ -190,23 +195,27 @@ void PyXPCOM_DLLRelease(void)
void pyxpcom_construct(void)
{
PRStatus status;
g_lockMain = PR_NewLock();
#ifndef PYXPCOM_USE_PYGILSTATE
PRStatus status;
status = PR_NewThreadPrivateIndex( &tlsIndex, NULL );
NS_WARN_IF_FALSE(status==0, "Could not allocate TLS storage");
if (NS_FAILED(status)) {
PR_DestroyLock(g_lockMain);
return; // PR_FALSE;
}
#endif // PYXPCOM_USE_PYGILSTATE
return; // PR_TRUE;
}
void pyxpcom_destruct(void)
{
PR_DestroyLock(g_lockMain);
#ifndef PYXPCOM_USE_PYGILSTATE
// I can't locate a way to kill this -
// should I pass a dtor to PR_NewThreadPrivateIndex??
// TlsFree(tlsIndex);
#endif // PYXPCOM_USE_PYGILSTATE
}
// Yet another attempt at cross-platform library initialization and finalization.

View File

@@ -47,6 +47,10 @@
#include "Python.h"
#if (PY_VERSION_HEX >= 0x02030000)
#define PYXPCOM_USE_PYGILSTATE
#endif
static char *PyTraceback_AsString(PyObject *exc_tb);
#ifdef XP_WIN
@@ -125,6 +129,7 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
}
// Get the Python interpreter state
NS_TIMELINE_START_TIMER("PyXPCOM: Python threadstate setup");
#ifndef PYXPCOM_USE_PYGILSTATE
PyThreadState *threadStateCreated = NULL;
PyThreadState *threadState = PyThreadState_Swap(NULL);
if (threadState==NULL) {
@@ -139,7 +144,9 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
}
PyEval_ReleaseLock();
PyEval_AcquireThread(threadState);
#else
PyGILState_STATE state = PyGILState_Ensure();
#endif // PYXPCOM_USE_PYGILSTATE
if (pfnEntryPoint == nsnull) {
PyObject *mod = PyImport_ImportModule("xpcom._xpcom");
if (mod==NULL) {
@@ -163,7 +170,8 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
// If the timeline service is installed, see if we can install our hooks.
if (NULL==PyImport_ImportModule("timeline_hook"))
PyErr_Clear(); // but don't care if we can't.
#endif
#endif
#ifndef PYXPCOM_USE_PYGILSTATE
// Abandon the thread-lock, as the first thing Python does
// is re-establish the lock (the Python thread-state story SUCKS!!!)
if (threadStateCreated) {
@@ -175,6 +183,10 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
if (threadStateSave)
PyThreadState_Delete(threadStateSave);
}
#else
PyGILState_Release(state);
#endif
NS_TIMELINE_STOP_TIMER("PyXPCOM: Python threadstate setup");
NS_TIMELINE_MARK_TIMER("PyXPCOM: Python threadstate setup");
NS_TIMELINE_START_TIMER("PyXPCOM: PyXPCOM NSGetModule entry point");

View File

@@ -46,12 +46,10 @@
#include "nsIProxyObjectManager.h"
PYXPCOM_EXPORT PyObject *PyXPCOM_Error = NULL;
extern void PyXPCOM_InterpreterState_Ensure();
extern PRInt32 _PyXPCOM_GetGatewayCount(void);
extern PRInt32 _PyXPCOM_GetInterfaceCount(void);
extern void AddDefaultGateway(PyObject *instance, nsISupports *gateway);
extern void PyXPCOM_InterpreterState_Ensure();
#ifdef XP_WIN
// Can only assume dynamic loading on Windows.
@@ -430,11 +428,17 @@ static struct PyMethodDef xpcom_methods[]=
////////////////////////////////////////////////////////////
// Other helpers/global functions.
//
#ifndef PYXPCOM_USE_PYGILSTATE
extern void PyXPCOM_InterpreterState_Ensure();
#endif
PRBool PyXPCOM_Globals_Ensure()
{
PRBool rc = PR_TRUE;
#ifndef PYXPCOM_USE_PYGILSTATE
PyXPCOM_InterpreterState_Ensure();
#endif
// The exception object - we load it from .py code!
if (PyXPCOM_Error == NULL) {