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:
@@ -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??
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user