VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/python/src/dllmain.cpp

Last change on this file was 103176, checked in by vboxsync, 3 months ago

libs/xpcom/python: Some cleanup, bugref:3409

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is the Python XPCOM language bindings.
15 *
16 * The Initial Developer of the Original Code is
17 * ActiveState Tool Corp.
18 * Portions created by the Initial Developer are Copyright (C) 2000
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 * Mark Hammond <mhammond@skippinet.com.au> (original author)
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38//
39// This code is part of the XPCOM extensions for Python.
40//
41// Written May 2000 by Mark Hammond.
42//
43// Based heavily on the Python COM support, which is
44// (c) Mark Hammond and Greg Stein.
45//
46// (c) 2000, ActiveState corp.
47
48#include "PyXPCOM_std.h"
49#include "nsILocalFile.h"
50
51#include <iprt/asm.h>
52#include <iprt/errcore.h>
53#include <iprt/semaphore.h>
54
55#ifdef XP_WIN
56#ifndef WIN32_LEAN_AND_MEAN
57#define WIN32_LEAN_AND_MEAN
58#endif
59#include "windows.h"
60#endif
61
62static volatile uint32_t g_cLockCount = 0;
63static RTSEMFASTMUTEX g_lockMain = NULL;
64
65PYXPCOM_EXPORT PyObject *PyXPCOM_Error = NULL;
66
67PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
68PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
69PyXPCOM_INTERFACE_DEFINE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
70PyXPCOM_INTERFACE_DEFINE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
71PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInterfaceInfo)
72PyXPCOM_INTERFACE_DEFINE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
73PyXPCOM_INTERFACE_DEFINE(Py_nsIClassInfo, nsIClassInfo, PyMethods_IClassInfo)
74PyXPCOM_INTERFACE_DEFINE(Py_nsIVariant, nsIVariant, PyMethods_IVariant)
75// deprecated, but retained for backward compatibility:
76PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManagerObsolete, nsIComponentManagerObsolete, PyMethods_IComponentManagerObsolete)
77
78////////////////////////////////////////////////////////////
79// Lock/exclusion global functions.
80//
81void PyXPCOM_AcquireGlobalLock(void)
82{
83 NS_PRECONDITION(g_lockMain != NIL_RTSEMFASTMUTEX, "Cant acquire a NULL lock!");
84 RTSemFastMutexRequest(g_lockMain);
85}
86void PyXPCOM_ReleaseGlobalLock(void)
87{
88 NS_PRECONDITION(g_lockMain != NIL_RTSEMFASTMUTEX, "Cant release a NULL lock!");
89 RTSemFastMutexRelease(g_lockMain);
90}
91
92void PyXPCOM_DLLAddRef(void)
93{
94 // Must be thread-safe, although cant have the Python lock!
95 CEnterLeaveXPCOMFramework _celf;
96 uint32_t cnt = ASMAtomicIncU32(&g_cLockCount);
97 if (cnt==1) { // First call
98 if (!Py_IsInitialized()) {
99 Py_Initialize();
100 // Make sure our Windows framework is all setup.
101 PyXPCOM_Globals_Ensure();
102 // Make sure we have _something_ as sys.argv.
103 if (PySys_GetObject((char*)"argv")==NULL) {
104 PyObject *path = PyList_New(0);
105#if PY_MAJOR_VERSION <= 2
106 PyObject *str = PyString_FromString("");
107#else
108 PyObject *str = PyUnicode_FromString("");
109#endif
110 PyList_Append(path, str);
111 PySys_SetObject((char*)"argv", path);
112 Py_XDECREF(path);
113 Py_XDECREF(str);
114 }
115
116 /* Done automatically since python 3.7 and deprecated since python 3.9. */
117#if PY_VERSION_HEX < 0x03090000
118 // Must force Python to start using thread locks, as
119 // we are free-threaded (maybe, I think, sometimes :-)
120 PyEval_InitThreads();
121#endif
122 // NOTE: We never finalize Python!!
123 }
124 }
125}
126void PyXPCOM_DLLRelease(void)
127{
128 ASMAtomicDecU32(&g_cLockCount);
129}
130
131static void pyxpcom_construct(void)
132{
133 int vrc = RTSemFastMutexCreate(&g_lockMain);
134 if (RT_FAILURE(vrc))
135 return;
136
137 return; // PR_TRUE;
138}
139
140static void pyxpcom_destruct(void)
141{
142 RTSemFastMutexDestroy(g_lockMain);
143}
144
145// Yet another attempt at cross-platform library initialization and finalization.
146struct DllInitializer {
147 DllInitializer() {
148 pyxpcom_construct();
149 }
150 ~DllInitializer() {
151 pyxpcom_destruct();
152 }
153} dll_initializer;
154
155////////////////////////////////////////////////////////////
156// Other helpers/global functions.
157//
158PRBool PyXPCOM_Globals_Ensure()
159{
160 PRBool rc = PR_TRUE;
161
162 // The exception object - we load it from .py code!
163 if (PyXPCOM_Error == NULL) {
164 rc = PR_FALSE;
165 PyObject *mod = NULL;
166
167 mod = PyImport_ImportModule("xpcom");
168 if (mod!=NULL) {
169 PyXPCOM_Error = PyObject_GetAttrString(mod, "Exception");
170 Py_DECREF(mod);
171 }
172 rc = (PyXPCOM_Error != NULL);
173 }
174 if (!rc)
175 return rc;
176
177 static PRBool bHaveInitXPCOM = PR_FALSE;
178 if (!bHaveInitXPCOM) {
179
180 if (!NS_IsXPCOMInitialized()) {
181 // not already initialized.
182 // Elsewhere, Mozilla can find it itself (we hope!)
183 nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
184 if (NS_FAILED(rv)) {
185 PyErr_SetString(PyExc_RuntimeError, "The XPCOM subsystem could not be initialized");
186 return PR_FALSE;
187 }
188 }
189 // Even if xpcom was already init, we want to flag it as init!
190 bHaveInitXPCOM = PR_TRUE;
191 // Register our custom interfaces.
192
193 Py_nsISupports::InitType();
194 Py_nsIComponentManager::InitType();
195 Py_nsIInterfaceInfoManager::InitType();
196 Py_nsIEnumerator::InitType();
197 Py_nsISimpleEnumerator::InitType();
198 Py_nsIInterfaceInfo::InitType();
199 Py_nsIInputStream::InitType();
200 Py_nsIClassInfo::InitType();
201 Py_nsIVariant::InitType();
202 // for backward compatibility:
203 Py_nsIComponentManagerObsolete::InitType();
204
205 }
206 return rc;
207}
208
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use