Add support for the timeline service. Not part of the build.

git-svn-id: svn://10.0.0.236/trunk@140547 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mhammond%skippinet.com.au 2003-04-02 04:00:17 +00:00
parent bac0f34e54
commit 8abc401471
2 changed files with 38 additions and 15 deletions

View File

@ -1044,19 +1044,13 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor
nsXPTCVariant &ns_v = m_var_array[value_index];
NS_ABORT_IF_FALSE(ns_v.type == td.type_flags, "Expecting variant all setup for us");
// NOTE: We NEVER pass Python internal buffers, even when a param is
// only marked as "in", for 2 reasons:
// * Paranoia - passing the internal "char *" buffer for a Python string
// means that the caller could potentially modify it, even though they
// shouldnt. This will be hard to track down, and will appear as tho
// Python itself has the bug, rather than the naughty object.
// * Simplicity - if the param is marked "in/out", we _must_ make
// a buffer copy anyway.
// The downside is speed - if a large buffer is passed as an "in" param,
// it is a shame to make a copy, then pass it, then free it, when it should
// be fine to simply pass the buffer.
// (The discussion above doesnt apply to ints and stuff - we can't
// even really get at the internal "int *" of a PyInt object.
// We used to avoid passing internal buffers to PyString etc objects
// for 2 reasons: paranoia (so incorrect external components couldn't break
// Python) and simplicity (in vs in-out issues, etc)
// However, at least one C++ implemented component (nsITimelineService)
// uses a "char *", and keys on the address (assuming that the same
// *pointer* is passed rather than value. Therefore, we have a special case
// - T_CHAR_STR that is "in" gets the Python string pointer passed.
void *&this_buffer_pointer = m_buffer_array[value_index]; // Freed at object destruction with PyMem_Free()
NS_ABORT_IF_FALSE(this_buffer_pointer==nsnull, "We appear to already have a buffer");
int cb_this_buffer_pointer = 0;
@ -1216,6 +1210,13 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor
ns_v.val.p = nsnull;
break;
}
// If an "in" char *, and we have a PyString, then pass the
// pointer (hoping everyone else plays by the rules too.
if (!XPT_PD_IS_OUT(td.param_flags) && PyString_Check(val)) {
ns_v.val.p = PyString_AS_STRING(val);
break;
}
if (!PyString_Check(val) && !PyUnicode_Check(val)) {
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
BREAK_FALSE;
@ -1237,6 +1238,12 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor
ns_v.val.p = nsnull;
break;
}
// If an "in" char *, and we have a PyString, then pass the
// pointer (hoping everyone else plays by the rules too.
if (!XPT_PD_IS_OUT(td.param_flags) && PyUnicode_Check(val)) {
ns_v.val.p = PyUnicode_AS_UNICODE(val);
break;
}
if (!PyString_Check(val) && !PyUnicode_Check(val)) {
PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
BREAK_FALSE;

View File

@ -59,6 +59,7 @@ static char *PyTraceback_AsString(PyObject *exc_tb);
#endif
#include "nsITimelineService.h"
typedef nsresult (*pfnPyXPCOM_NSGetModule)(nsIComponentManager *servMgr,
nsIFile* location,
@ -108,6 +109,7 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
#endif
PRBool bDidInitPython = !Py_IsInitialized(); // well, I will next line, anyway :-)
if (bDidInitPython) {
NS_TIMELINE_START_TIMER("PyXPCOM: Python initializing");
Py_Initialize();
if (!Py_IsInitialized()) {
LogError("Python initialization failed!\n");
@ -118,8 +120,11 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
#endif // NS_DEBUG
AddStandardPaths();
PyEval_InitThreads();
NS_TIMELINE_STOP_TIMER("PyXPCOM: Python initializing");
NS_TIMELINE_MARK_TIMER("PyXPCOM: Python initializing");
}
// Get the Python interpreter state
NS_TIMELINE_START_TIMER("PyXPCOM: Python threadstate setup");
PyThreadState *threadStateCreated = NULL;
PyThreadState *threadState = PyThreadState_Swap(NULL);
if (threadState==NULL) {
@ -153,7 +158,12 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
LogError("Could not load main Python entry point\n");
return NS_ERROR_FAILURE;
}
#ifdef MOZ_TIMELINE
// 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
// Abandon the thread-lock, as the first thing Python does
// is re-establish the lock (the Python thread-state story SUCKS!!!)
if (threadStateCreated) {
@ -165,7 +175,13 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
if (threadStateSave)
PyThreadState_Delete(threadStateSave);
}
return (*pfnEntryPoint)(servMgr, location, result);
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");
nsresult rc = (*pfnEntryPoint)(servMgr, location, result);
NS_TIMELINE_STOP_TIMER("PyXPCOM: PyXPCOM NSGetModule entry point");
NS_TIMELINE_MARK_TIMER("PyXPCOM: PyXPCOM NSGetModule entry point");
return rc;
}
// The internal helper that actually moves the