Changeset 101955 in vbox
- Timestamp:
- Nov 8, 2023 10:23:22 AM (15 months ago)
- Location:
- trunk/src/libs/xpcom18a4/python/src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/python/src/ErrorUtils.cpp
r101919 r101955 52 52 # include <iprt/err.h> 53 53 # include <iprt/string.h> 54 # endif55 # include "nspr.h" // PR_fprintf54 # include <iprt/stream.h> 55 #endif 56 56 57 57 static char *PyTraceback_AsString(PyObject *exc_tb); … … 63 63 static void _PanicErrorWrite(const char *msg) 64 64 { 65 PR_fprintf(PR_STDERR,"%s\n", msg);65 RTStrmPrintf(g_pStdErr,"%s\n", msg); 66 66 } 67 67 … … 152 152 static void VLogF(const char *methodName, const char *fmt, va_list argptr) 153 153 { 154 char buff[512]; 155 #ifdef VBOX /* Enable the use of VBox formatting types. */ 156 RTStrPrintfV(buff, sizeof(buff), fmt, argptr); 157 #else 158 // Use safer NS_ functions. 159 PR_vsnprintf(buff, sizeof(buff), fmt, argptr); 160 #endif 161 162 LogMessage(methodName, buff); 163 } 164 165 PRBool PyXPCOM_FormatCurrentException(nsCString &streamout) 166 { 167 PRBool ok = PR_FALSE; 154 char buff[512]; 155 RTStrPrintfV(buff, sizeof(buff), fmt, argptr); 156 157 LogMessage(methodName, buff); 158 } 159 160 bool PyXPCOM_FormatCurrentException(nsCString &streamout) 161 { 162 bool ok = false; 168 163 PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL; 169 164 PyErr_Fetch( &exc_typ, &exc_val, &exc_tb); … … 177 172 } 178 173 179 PRBool PyXPCOM_FormatGivenException(nsCString &streamout,174 bool PyXPCOM_FormatGivenException(nsCString &streamout, 180 175 PyObject *exc_typ, PyObject *exc_val, 181 176 PyObject *exc_tb) 182 177 { 183 178 if (!exc_typ) 184 return PR_FALSE;179 return false; 185 180 streamout += "\n"; 186 181 … … 218 213 streamout += "Can't convert exception value to a string!"; 219 214 } 220 return PR_TRUE;215 return true; 221 216 } 222 217 … … 232 227 // traceback to be in the same buffer. 233 228 char buff[512]; 234 PR_vsnprintf(buff, sizeof(buff), fmt, marker);229 RTStrPrintf2V(buff, sizeof(buff), fmt, marker); 235 230 // If we have a Python exception, also log that: 236 231 nsCAutoString streamout(buff); … … 287 282 nsXPIDLCString emsg; 288 283 ex->GetMessage(getter_Copies(emsg)); 289 PR_snprintf(msg, sizeof(msg), "%s",290 emsg.get());284 RTStrPrintf2(msg, sizeof(msg), "%s", 285 emsg.get()); 291 286 gotMsg = true; 292 287 } … … 300 295 if (strncmp(pMsg->pszMsgFull, "Unknown", 7) != 0) 301 296 { 302 PR_snprintf(msg, sizeof(msg), "%s (%s)",303 pMsg->pszMsgFull, pMsg->pszDefine);297 RTStrPrintf2(msg, sizeof(msg), "%s (%s)", 298 pMsg->pszMsgFull, pMsg->pszDefine); 304 299 gotMsg = true; 305 300 } … … 308 303 if (!gotMsg) 309 304 { 310 PR_snprintf(msg, sizeof(msg), "Error 0x%x in module 0x%x",311 NS_ERROR_GET_CODE(r), NS_ERROR_GET_MODULE(r));305 RTStrPrintf2(msg, sizeof(msg), "Error 0x%x in module 0x%x", 306 NS_ERROR_GET_CODE(r), NS_ERROR_GET_MODULE(r)); 312 307 } 313 308 PyObject *evalue = Py_BuildValue("is", r, msg); -
trunk/src/libs/xpcom18a4/python/src/PyGBase.cpp
r86333 r101955 52 52 #include <nsIInputStream.h> 53 53 54 static PRInt32 cGateways = 0; 55 PRInt32 _PyXPCOM_GetGatewayCount(void) 54 #include <iprt/asm.h> 55 56 static uint32_t cGateways = 0; 57 uint32_t _PyXPCOM_GetGatewayCount(void) 56 58 { 57 59 return cGateways; … … 95 97 { 96 98 // Note that "instance" is the _policy_ instance!! 97 PR_AtomicIncrement(&cGateways);99 ASMAtomicIncU32(&cGateways); 98 100 m_pBaseObject = GetDefaultGateway(instance); 99 101 // m_pWeakRef is an nsCOMPtr and needs no init. … … 160 162 PyG_Base::~PyG_Base() 161 163 { 162 PR_AtomicDecrement(&cGateways);164 ASMAtomicDecU32(&cGateways); 163 165 #ifdef DEBUG_LIFETIMES 164 166 PYXPCOM_LOG_DEBUG("PyG_Base: deleted %p", this); … … 422 424 PyG_Base::AddRef(void) 423 425 { 424 nsrefcnt cnt = (nsrefcnt) PR_AtomicIncrement((PRInt32*)&mRefCnt);426 nsrefcnt cnt = (nsrefcnt) ASMAtomicIncS32((volatile int32_t*)&mRefCnt); 425 427 #ifdef NS_BUILD_REFCNT_LOGGING 426 428 // If we have no pBaseObject, then we need to ignore them … … 434 436 PyG_Base::Release(void) 435 437 { 436 nsrefcnt cnt = (nsrefcnt) PR_AtomicDecrement((PRInt32*)&mRefCnt);438 nsrefcnt cnt = (nsrefcnt) ASMAtomicDecS32((volatile int32_t*)&mRefCnt); 437 439 #ifdef NS_BUILD_REFCNT_LOGGING 438 440 if (m_pBaseObject == NULL) -
trunk/src/libs/xpcom18a4/python/src/PyISupports.cpp
r90632 r101955 49 49 #include "nsISupportsPrimitives.h" 50 50 51 static PRInt32 cInterfaces=0; 51 #include <iprt/asm.h> 52 53 static volatile uint32_t cInterfaces=0; 52 54 static PyObject *g_obFuncMakeInterfaceCount = NULL; // XXX - never released!!! 53 55 … … 123 125 } 124 126 125 PRInt32 127 uint32_t 126 128 _PyXPCOM_GetInterfaceCount(void) 127 129 { 128 return cInterfaces;130 return ASMAtomicReadU32(&cInterfaces); 129 131 } 130 132 … … 144 146 m_iid = iid; 145 147 // refcnt of object managed by caller. 146 PR_AtomicIncrement(&cInterfaces);148 ASMAtomicIncU32(&cInterfaces); 147 149 PyXPCOM_DLLAddRef(); 148 150 #if 1 /* VBox: Must use for 3.9+, includes _Py_NewReferences. Works for all older versions too. @bugref{10079} */ … … 172 174 173 175 SafeRelease(this); 174 PR_AtomicDecrement(&cInterfaces);176 ASMAtomicDecU32(&cInterfaces); 175 177 PyXPCOM_DLLRelease(); 176 178 } -
trunk/src/libs/xpcom18a4/python/src/PyXPCOM.h
r101831 r101955 298 298 299 299 // Write current exception and traceback to a string. 300 PYXPCOM_EXPORT PRBool PyXPCOM_FormatCurrentException(nsCString &streamout);300 PYXPCOM_EXPORT bool PyXPCOM_FormatCurrentException(nsCString &streamout); 301 301 // Write specified exception and traceback to a string. 302 PYXPCOM_EXPORT PRBool PyXPCOM_FormatGivenException(nsCString &streamout,302 PYXPCOM_EXPORT bool PyXPCOM_FormatGivenException(nsCString &streamout, 303 303 PyObject *exc_typ, PyObject *exc_val, 304 304 PyObject *exc_tb); … … 749 749 extern PYXPCOM_EXPORT void AddDefaultGateway(PyObject *instance, nsISupports *gateway); 750 750 751 extern PYXPCOM_EXPORT PRInt32_PyXPCOM_GetGatewayCount(void);752 extern PYXPCOM_EXPORT PRInt32_PyXPCOM_GetInterfaceCount(void);751 extern PYXPCOM_EXPORT uint32_t _PyXPCOM_GetGatewayCount(void); 752 extern PYXPCOM_EXPORT uint32_t _PyXPCOM_GetInterfaceCount(void); 753 753 #ifdef VBOX_DEBUG_LIFETIMES 754 754 extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_DumpInterfaces(void); … … 877 877 PYXPCOM_EXPORT PRBool PyXPCOM_Globals_Ensure(); 878 878 879 // For 2.3, use the PyGILState_ calls880 #if (PY_VERSION_HEX >= 0x02030000)881 #define PYXPCOM_USE_PYGILSTATE882 #endif883 884 #ifdef PYXPCOM_USE_PYGILSTATE885 879 class CEnterLeavePython { 886 880 public: … … 902 896 PyGILState_STATE state; 903 897 }; 904 #else905 906 extern PYXPCOM_EXPORT PyInterpreterState *PyXPCOM_InterpreterState;907 PYXPCOM_EXPORT PRBool PyXPCOM_ThreadState_Ensure();908 PYXPCOM_EXPORT void PyXPCOM_ThreadState_Free();909 PYXPCOM_EXPORT void PyXPCOM_ThreadState_Clear();910 PYXPCOM_EXPORT void PyXPCOM_InterpreterLock_Acquire();911 PYXPCOM_EXPORT void PyXPCOM_InterpreterLock_Release();912 913 // Pre 2.3 thread-state dances.914 class CEnterLeavePython {915 public:916 CEnterLeavePython() {917 created = PyXPCOM_ThreadState_Ensure();918 PyXPCOM_InterpreterLock_Acquire();919 if (created) {920 // If pending python calls are waiting as we enter Python,921 // it will generally mean an asynch signal handler, etc.922 // We can either call it here, or wait for Python to call it923 // as part of its "even 'n' opcodes" check. If we wait for924 // Python to check it and the pending call raises an exception,925 // then it is _our_ code that will fail - this is unfair,926 // as the signal was raised before we were entered - indeed,927 // we may be directly responding to the signal!928 // Thus, we flush all the pending calls here, and report any929 // exceptions via our normal exception reporting mechanism.930 // We can then execute our code in the knowledge that only931 // signals raised _while_ we are executing will cause exceptions.932 PyXPCOM_MakePendingCalls();933 }934 }935 ~CEnterLeavePython() {936 // The interpreter state must be cleared937 // _before_ we release the lock, as some of938 // the sys. attributes cleared (eg, the current exception)939 // may need the lock to invoke their destructors -940 // specifically, when exc_value is a class instance, and941 // the exception holds the last reference!942 if ( created )943 PyXPCOM_ThreadState_Clear();944 PyXPCOM_InterpreterLock_Release();945 if ( created )946 PyXPCOM_ThreadState_Free();947 }948 private:949 PRBool created;950 };951 #endif // PYXPCOM_USE_PYGILSTATE952 898 953 899 // Our classes. -
trunk/src/libs/xpcom18a4/python/src/dllmain.cpp
r101939 r101955 49 49 #include "nsILocalFile.h" 50 50 51 #include <iprt/asm.h> 52 #include <iprt/errcore.h> 53 #include <iprt/semaphore.h> 54 51 55 #ifdef XP_WIN 52 56 #ifndef WIN32_LEAN_AND_MEAN … … 56 60 #endif 57 61 58 static PRInt32g_cLockCount = 0;59 static PRLock *g_lockMain = nsnull;62 static volatile uint32_t g_cLockCount = 0; 63 static RTSEMFASTMUTEX g_lockMain = NULL; 60 64 61 65 PYXPCOM_EXPORT PyObject *PyXPCOM_Error = NULL; … … 72 76 PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManagerObsolete, nsIComponentManagerObsolete, PyMethods_IComponentManagerObsolete) 73 77 74 #ifndef PYXPCOM_USE_PYGILSTATE75 76 ////////////////////////////////////////////////////////////77 // Thread-state helpers/global functions.78 // Only used if there is no Python PyGILState_* API79 //80 static PyThreadState *ptsGlobal = nsnull;81 PyInterpreterState *PyXPCOM_InterpreterState = nsnull;82 PRUintn tlsIndex = 0;83 84 85 // This function must be called at some time when the interpreter lock and state is valid.86 // Called by init{module} functions and also COM factory entry point.87 void PyXPCOM_InterpreterState_Ensure()88 {89 if (PyXPCOM_InterpreterState==NULL) {90 PyThreadState *threadStateSave = PyThreadState_Swap(NULL);91 if (threadStateSave==NULL)92 Py_FatalError("Can not setup interpreter state, as current state is invalid");93 94 PyXPCOM_InterpreterState = threadStateSave->interp;95 PyThreadState_Swap(threadStateSave);96 }97 }98 99 void PyXPCOM_InterpreterState_Free()100 {101 PyXPCOM_ThreadState_Free();102 PyXPCOM_InterpreterState = NULL; // Eek - should I be freeing something?103 }104 105 // This structure is stored in the TLS slot. At this stage only a Python thread state106 // is kept, but this may change in the future...107 struct ThreadData{108 PyThreadState *ts;109 };110 111 // Ensure that we have a Python thread state available to use.112 // If this is called for the first time on a thread, it will allocate113 // the thread state. This does NOT change the state of the Python lock.114 // Returns TRUE if a new thread state was created, or FALSE if a115 // thread state already existed.116 PRBool PyXPCOM_ThreadState_Ensure()117 {118 ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);119 if (pData==NULL) { /* First request on this thread */120 /* Check we have an interpreter state */121 if (PyXPCOM_InterpreterState==NULL) {122 Py_FatalError("Can not setup thread state, as have no interpreter state");123 }124 pData = (ThreadData *)nsMemory::Alloc(sizeof(ThreadData));125 if (!pData)126 Py_FatalError("Out of memory allocating thread state.");127 memset(pData, 0, sizeof(*pData));128 if (NS_FAILED( PR_SetThreadPrivate( tlsIndex, pData ) ) ) {129 NS_ABORT_IF_FALSE(0, "Could not create thread data for this thread!");130 Py_FatalError("Could not thread private thread data!");131 }132 pData->ts = PyThreadState_New(PyXPCOM_InterpreterState);133 return PR_TRUE; // Did create a thread state state134 }135 return PR_FALSE; // Thread state was previously created136 }137 138 // Asuming we have a valid thread state, acquire the Python lock.139 void PyXPCOM_InterpreterLock_Acquire()140 {141 ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);142 NS_ABORT_IF_FALSE(pData, "Have no thread data for this thread!");143 PyThreadState *thisThreadState = pData->ts;144 PyEval_AcquireThread(thisThreadState);145 }146 147 // Asuming we have a valid thread state, release the Python lock.148 void PyXPCOM_InterpreterLock_Release()149 {150 ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);151 NS_ABORT_IF_FALSE(pData, "Have no thread data for this thread!");152 PyThreadState *thisThreadState = pData->ts;153 PyEval_ReleaseThread(thisThreadState);154 }155 156 // Free the thread state for the current thread157 // (Presumably previously create with a call to158 // PyXPCOM_ThreadState_Ensure)159 void PyXPCOM_ThreadState_Free()160 {161 ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);162 if (!pData) return;163 PyThreadState *thisThreadState = pData->ts;164 PyThreadState_Delete(thisThreadState);165 PR_SetThreadPrivate(tlsIndex, NULL);166 nsMemory::Free(pData);167 }168 169 void PyXPCOM_ThreadState_Clear()170 {171 ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);172 PyThreadState *thisThreadState = pData->ts;173 PyThreadState_Clear(thisThreadState);174 }175 #endif // PYXPCOM_USE_PYGILSTATE176 177 78 //////////////////////////////////////////////////////////// 178 79 // Lock/exclusion global functions. … … 180 81 void PyXPCOM_AcquireGlobalLock(void) 181 82 { 182 NS_PRECONDITION(g_lockMain != nsnull, "Cant acquire a NULL lock!");183 PR_Lock(g_lockMain);83 NS_PRECONDITION(g_lockMain != NIL_RTSEMFASTMUTEX, "Cant acquire a NULL lock!"); 84 RTSemFastMutexRequest(g_lockMain); 184 85 } 185 86 void PyXPCOM_ReleaseGlobalLock(void) 186 87 { 187 NS_PRECONDITION(g_lockMain != nsnull, "Cant release a NULL lock!");188 PR_Unlock(g_lockMain);88 NS_PRECONDITION(g_lockMain != NIL_RTSEMFASTMUTEX, "Cant release a NULL lock!"); 89 RTSemFastMutexRelease(g_lockMain); 189 90 } 190 91 … … 193 94 // Must be thread-safe, although cant have the Python lock! 194 95 CEnterLeaveXPCOMFramework _celf; 195 PRInt32 cnt = PR_AtomicIncrement(&g_cLockCount);96 uint32_t cnt = ASMAtomicIncU32(&g_cLockCount); 196 97 if (cnt==1) { // First call 197 98 if (!Py_IsInitialized()) { … … 219 120 PyEval_InitThreads(); 220 121 #endif 221 #ifndef PYXPCOM_USE_PYGILSTATE222 // Release Python lock, as first thing we do is re-get it.223 ptsGlobal = PyEval_SaveThread();224 #endif225 122 // NOTE: We never finalize Python!! 226 123 } … … 229 126 void PyXPCOM_DLLRelease(void) 230 127 { 231 PR_AtomicDecrement(&g_cLockCount);128 ASMAtomicDecU32(&g_cLockCount); 232 129 } 233 130 234 131 void pyxpcom_construct(void) 235 132 { 236 g_lockMain = PR_NewLock(); 237 #ifndef PYXPCOM_USE_PYGILSTATE 238 PRStatus status; 239 status = PR_NewThreadPrivateIndex( &tlsIndex, NULL ); 240 NS_WARN_IF_FALSE(status==0, "Could not allocate TLS storage"); 241 if (NS_FAILED(status)) { 242 PR_DestroyLock(g_lockMain); 243 return; // PR_FALSE; 244 } 245 #endif // PYXPCOM_USE_PYGILSTATE 246 return; // PR_TRUE; 133 int vrc = RTSemFastMutexCreate(&g_lockMain); 134 if (RT_FAILURE(vrc)) 135 return; 136 137 return; // PR_TRUE; 247 138 } 248 139 249 140 void pyxpcom_destruct(void) 250 141 { 251 PR_DestroyLock(g_lockMain); 252 #ifndef PYXPCOM_USE_PYGILSTATE 253 // I can't locate a way to kill this - 254 // should I pass a dtor to PR_NewThreadPrivateIndex?? 255 // TlsFree(tlsIndex); 256 #endif // PYXPCOM_USE_PYGILSTATE 142 RTSemFastMutexDestroy(g_lockMain); 257 143 } 258 144 … … 273 159 { 274 160 PRBool rc = PR_TRUE; 275 276 #ifndef PYXPCOM_USE_PYGILSTATE277 PyXPCOM_InterpreterState_Ensure();278 #endif279 161 280 162 // The exception object - we load it from .py code! -
trunk/src/libs/xpcom18a4/python/src/module/_xpcom.cpp
r101939 r101955 69 69 #define LOADER_LINKS_WITH_PYTHON 70 70 71 #ifndef PYXPCOM_USE_PYGILSTATE72 extern PYXPCOM_EXPORT void PyXPCOM_InterpreterState_Ensure();73 #endif74 75 71 #ifdef VBOX_PYXPCOM 76 72 # include <iprt/cdefs.h>
Note:
See TracChangeset
for help on using the changeset viewer.