From 50caa43aa245679171bbc07141df3f893ec12d98 Mon Sep 17 00:00:00 2001 From: "mhammond%skippinet.com.au" Date: Sun, 20 Apr 2003 02:47:31 +0000 Subject: [PATCH] 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 --- mozilla/extensions/python/xpcom/src/PyXPCOM.h | 31 +++++++++++++++++-- .../extensions/python/xpcom/src/dllmain.cpp | 19 +++++++++--- .../python/xpcom/src/loader/pyloader.cpp | 16 ++++++++-- mozilla/extensions/python/xpcom/src/xpcom.cpp | 8 +++-- 4 files changed, 62 insertions(+), 12 deletions(-) diff --git a/mozilla/extensions/python/xpcom/src/PyXPCOM.h b/mozilla/extensions/python/xpcom/src/PyXPCOM.h index 9e64647e197..84ed6513763 100644 --- a/mozilla/extensions/python/xpcom/src/PyXPCOM.h +++ b/mozilla/extensions/python/xpcom/src/PyXPCOM.h @@ -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?? diff --git a/mozilla/extensions/python/xpcom/src/dllmain.cpp b/mozilla/extensions/python/xpcom/src/dllmain.cpp index 2707e82d6a8..ac02a5304b9 100644 --- a/mozilla/extensions/python/xpcom/src/dllmain.cpp +++ b/mozilla/extensions/python/xpcom/src/dllmain.cpp @@ -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. diff --git a/mozilla/extensions/python/xpcom/src/loader/pyloader.cpp b/mozilla/extensions/python/xpcom/src/loader/pyloader.cpp index 9f2982d1b2b..dffe62e893b 100644 --- a/mozilla/extensions/python/xpcom/src/loader/pyloader.cpp +++ b/mozilla/extensions/python/xpcom/src/loader/pyloader.cpp @@ -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"); diff --git a/mozilla/extensions/python/xpcom/src/xpcom.cpp b/mozilla/extensions/python/xpcom/src/xpcom.cpp index e76505ffd8f..0004db60f26 100644 --- a/mozilla/extensions/python/xpcom/src/xpcom.cpp +++ b/mozilla/extensions/python/xpcom/src/xpcom.cpp @@ -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) {