X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/493f1553fdfd276ed9944c5f1c070ee34be13b52..4649b5eded522cdc6d76aae074f98a2c162fd648:/wxPython/src/helpers.cpp diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index d6492ce70e..0d7aa40850 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -101,7 +101,8 @@ void WXDLLEXPORT wxEntryCleanup(); #ifdef WXP_WITH_THREAD -PyThreadState* wxPyEventThreadState = NULL; +//PyThreadState* wxPyEventThreadState = NULL; +PyInterpreterState* wxPyInterpreter = NULL; #endif @@ -117,7 +118,8 @@ void __wxPreStart() #ifdef WXP_WITH_THREAD PyEval_InitThreads(); - wxPyEventThreadState = PyThreadState_Get(); // PyThreadState_New(PyThreadState_Get()->interp); +// wxPyEventThreadState = PyThreadState_Get(); // PyThreadState_New(PyThreadState_Get()->interp); + wxPyInterpreter = PyThreadState_Get()->interp; #endif // Bail out if there is already windows created. This means that the @@ -374,43 +376,71 @@ PyObject* wxPyConstructObject(void* ptr, //--------------------------------------------------------------------------- -static PyThreadState* myPyThreadState_Get() { - PyThreadState* current; - current = PyThreadState_Swap(NULL); - PyThreadState_Swap(current); - return current; -} - - -bool wxPyRestoreThread() { - // NOTE: The Python API docs state that if a thread already has the - // interpreter lock and calls PyEval_RestoreThread again a deadlock - // occurs, so I put in this code as a guard condition since there are - // many possibilites for nested events and callbacks in wxPython. If - // The current thread is our thread, then we can assume that we - // already have the lock. (I hope!) - // +// static PyThreadState* myPyThreadState_Get() { +// PyThreadState* current; +// current = PyThreadState_Swap(NULL); +// PyThreadState_Swap(current); +// return current; +// } + + +// bool wxPyRestoreThread() { +// // NOTE: The Python API docs state that if a thread already has the +// // interpreter lock and calls PyEval_RestoreThread again a deadlock +// // occurs, so I put in this code as a guard condition since there are +// // many possibilites for nested events and callbacks in wxPython. If +// // The current thread is our thread, then we can assume that we +// // already have the lock. (I hope!) +// // +// #ifdef WXP_WITH_THREAD +// if (wxPyEventThreadState != myPyThreadState_Get()) { +// PyEval_AcquireThread(wxPyEventThreadState); +// return TRUE; +// } +// else +// #endif +// return FALSE; +// } + + +// void wxPySaveThread(bool doSave) { +// #ifdef WXP_WITH_THREAD +// if (doSave) { +// PyEval_ReleaseThread(wxPyEventThreadState); +// } +// #endif +// } + + + +wxPyTState* wxPyBeginBlockThreads() { + wxPyTState* state = NULL; #ifdef WXP_WITH_THREAD - if (wxPyEventThreadState != myPyThreadState_Get()) { - PyEval_AcquireThread(wxPyEventThreadState); - return TRUE; + if (1) { // Can I check if I've already got the lock? + state = new wxPyTState; + PyEval_AcquireLock(); + state->newState = PyThreadState_New(wxPyInterpreter); + state->prevState = PyThreadState_Swap(state->newState); } - else #endif - return FALSE; + return state; } -void wxPySaveThread(bool doSave) { +void wxPyEndBlockThreads(wxPyTState* state) { #ifdef WXP_WITH_THREAD - if (doSave) { - PyEval_ReleaseThread(wxPyEventThreadState); + if (state) { + PyThreadState_Swap(state->prevState); + PyThreadState_Clear(state->newState); + PyEval_ReleaseLock(); + PyThreadState_Delete(state->newState); + delete state; } #endif } -//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject); @@ -425,9 +455,9 @@ wxPyCallback::wxPyCallback(const wxPyCallback& other) { } wxPyCallback::~wxPyCallback() { - bool doSave = wxPyRestoreThread(); + wxPyTState* state = wxPyBeginBlockThreads(); Py_DECREF(m_func); - wxPySaveThread(doSave); + wxPyEndBlockThreads(state); } @@ -441,7 +471,7 @@ void wxPyCallback::EventThunker(wxEvent& event) { PyObject* tuple; - bool doSave = wxPyRestoreThread(); + wxPyTState* state = wxPyBeginBlockThreads(); wxString className = event.GetClassInfo()->GetClassName(); if (className == "wxPyEvent") @@ -457,11 +487,11 @@ void wxPyCallback::EventThunker(wxEvent& event) { Py_DECREF(tuple); if (result) { Py_DECREF(result); - PyErr_Clear(); + PyErr_Clear(); // Just in case... } else { PyErr_Print(); } - wxPySaveThread(doSave); + wxPyEndBlockThreads(state); } @@ -564,12 +594,12 @@ PyObject* wxPyCBH_callCallbackObj(const wxPyCallbackHelper& cbh, PyObject* argTu void wxPyCBH_delete(wxPyCallbackHelper* cbh) { - bool doSave = wxPyRestoreThread(); if (cbh->m_incRef) { + wxPyTState* state = wxPyBeginBlockThreads(); Py_XDECREF(cbh->m_self); Py_XDECREF(cbh->m_class); + wxPyEndBlockThreads(state); } - wxPySaveThread(doSave); } //--------------------------------------------------------------------------- @@ -586,14 +616,14 @@ wxPyEvtSelfRef::wxPyEvtSelfRef() { } wxPyEvtSelfRef::~wxPyEvtSelfRef() { - bool doSave = wxPyRestoreThread(); + wxPyTState* state = wxPyBeginBlockThreads(); if (m_cloned) Py_DECREF(m_self); - wxPySaveThread(doSave); + wxPyEndBlockThreads(state); } void wxPyEvtSelfRef::SetSelf(PyObject* self, bool clone) { - bool doSave = wxPyRestoreThread(); + wxPyTState* state = wxPyBeginBlockThreads(); if (m_cloned) Py_DECREF(m_self); m_self = self; @@ -601,7 +631,7 @@ void wxPyEvtSelfRef::SetSelf(PyObject* self, bool clone) { Py_INCREF(m_self); m_cloned = TRUE; } - wxPySaveThread(doSave); + wxPyEndBlockThreads(state); } PyObject* wxPyEvtSelfRef::GetSelf() const { @@ -654,9 +684,9 @@ wxPyTimer::wxPyTimer(PyObject* callback) { } wxPyTimer::~wxPyTimer() { - bool doSave = wxPyRestoreThread(); + wxPyTState* state = wxPyBeginBlockThreads(); Py_DECREF(func); - wxPySaveThread(doSave); + wxPyEndBlockThreads(state); } void wxPyTimer::Notify() { @@ -664,7 +694,7 @@ void wxPyTimer::Notify() { wxTimer::Notify(); } else { - bool doSave = wxPyRestoreThread(); + wxPyTState* state = wxPyBeginBlockThreads(); PyObject* result; PyObject* args = Py_BuildValue("()"); @@ -678,7 +708,7 @@ void wxPyTimer::Notify() { PyErr_Print(); } - wxPySaveThread(doSave); + wxPyEndBlockThreads(state); } } @@ -694,7 +724,7 @@ PyObject* wxPy_ConvertList(wxListBase* list, const char* className) { wxObject* wxObj; wxNode* node = list->First(); - bool doSave = wxPyRestoreThread(); + wxPyTState* state = wxPyBeginBlockThreads(); pyList = PyList_New(0); while (node) { wxObj = node->Data(); @@ -702,7 +732,7 @@ PyObject* wxPy_ConvertList(wxListBase* list, const char* className) { PyList_Append(pyList, pyObj); node = node->Next(); } - wxPySaveThread(doSave); + wxPyEndBlockThreads(state); return pyList; } @@ -981,11 +1011,24 @@ wxString* wxString_LIST_helper(PyObject* source) { } for (int x=0; x= 1009 + if (! PyString_Check(o) && ! PyUnicode_Check(o)) { + PyErr_SetString(PyExc_TypeError, "Expected a list of string or unicode objects."); + return NULL; + } + + char* buff; + int length; + if (PyString_AsStringAndSize(o, &buff, &length) == -1) + return NULL; + temp[x] = wxString(buff, length); +#else if (! PyString_Check(o)) { PyErr_SetString(PyExc_TypeError, "Expected a list of strings."); return NULL; } temp[x] = PyString_AsString(o); +#endif } return temp; } @@ -1016,10 +1059,7 @@ wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) { PyObject* o1 = PyTuple_GetItem(o, 0); PyObject* o2 = PyTuple_GetItem(o, 1); PyObject* o3 = PyTuple_GetItem(o, 2); - - temp[x].m_flags = PyInt_AsLong(o1); - temp[x].m_keyCode = PyInt_AsLong(o2); - temp[x].m_command = PyInt_AsLong(o3); + temp[x].Set(PyInt_AsLong(o1), PyInt_AsLong(o2), PyInt_AsLong(o3)); } else { PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");