Acquire the GIL for INCREF's where needed

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@70901 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2012-03-14 20:56:04 +00:00
parent e9a0da2888
commit f525cad436
8 changed files with 61 additions and 47 deletions

View File

@@ -392,6 +392,7 @@ def checkForUnitTestModule(module):
def convertTwoIntegersTemplate(CLASS):
# Note: The GIL is already acquired where this code is used.
return """\
// is it just a typecheck?
if (!sipIsErr) {{
@@ -431,6 +432,7 @@ def convertTwoIntegersTemplate(CLASS):
def convertFourIntegersTemplate(CLASS):
# Note: The GIL is already acquired where this code is used.
return """\
// is it just a typecheck?
if (!sipIsErr) {{
@@ -477,6 +479,7 @@ def convertFourIntegersTemplate(CLASS):
def convertTwoDoublesTemplate(CLASS):
# Note: The GIL is already acquired where this code is used.
return """\
// is it just a typecheck?
if (!sipIsErr) {{
@@ -516,6 +519,7 @@ def convertTwoDoublesTemplate(CLASS):
def convertFourDoublesTemplate(CLASS):
# Note: The GIL is already acquired where this code is used.
return """\
// is it just a typecheck?
if (!sipIsErr) {{
@@ -628,7 +632,7 @@ public:
sipRes = ({ItemClass}*)node->GetData();
}}
else {{
PyErr_SetString(PyExc_IndexError, "sequence index out of range");
wxPyErr_SetString(PyExc_IndexError, "sequence index out of range");
sipError = sipErrorFail;
}}
%End
@@ -651,9 +655,9 @@ public:
int idx = sipCpp->IndexOf(({RealItemClass}*)obj);
if (idx == wxNOT_FOUND) {{
sipError = sipErrorFail;
PyErr_SetString(PyExc_ValueError,
"sequence.index(x): x not in sequence");
}}
wxPyErr_SetString(PyExc_ValueError,
"sequence.index(x): x not in sequence");
}}
sipRes = idx;
%End
@@ -758,7 +762,7 @@ public:
sipRes = &sipCpp->Item(index);
}}
else {{
PyErr_SetString(PyExc_IndexError, "sequence index out of range");
wxPyErr_SetString(PyExc_IndexError, "sequence index out of range");
sipError = sipErrorFail;
}}
%End
@@ -780,8 +784,8 @@ public:
int idx = sipCpp->Index(*obj, false);
if (idx == wxNOT_FOUND) {{
sipError = sipErrorFail;
PyErr_SetString(PyExc_ValueError,
"sequence.index(x): x not in sequence");
wxPyErr_SetString(PyExc_ValueError,
"sequence.index(x): x not in sequence");
}}
sipRes = idx;
%End
@@ -821,6 +825,7 @@ static
{{
{objType}* array;
Py_ssize_t idx, len;
wxPyBlock_t blocked = wxPyBeginBlockThreads();
// ensure that it is a sequence
if (! PySequence_Check(source))
@@ -846,6 +851,7 @@ static
array = new {objType}[*count];
if (!array) {{
PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
wxPyEndBlockThreads(blocked);
return NULL;
}}
for (idx=0; idx<len; idx++) {{
@@ -858,10 +864,12 @@ static
sipReleaseType((void*)item, {sipType}, state); // delete temporary instances
Py_DECREF(obj);
}}
wxPyEndBlockThreads(blocked);
return array;
error0:
PyErr_SetString(PyExc_TypeError, "{errmsg}");
wxPyEndBlockThreads(blocked);
return NULL;
}}
""".format(**locals())

View File

@@ -19,15 +19,14 @@
{
m_obj = obj;
m_incRef = incref;
if (incref)
Py_INCREF(m_obj);
if (incref) {
wxPyBLOCK_THREADS( Py_INCREF(m_obj) );
}
}
~wxPyClientData()
{
if (m_incRef) {
// TODO: wxPyBlock_t blocked = wxPyBeginBlockThreads();
Py_DECREF(m_obj);
//wxPyEndBlockThreads(blocked);
wxPyBLOCK_THREADS( Py_DECREF(m_obj) );
}
m_obj = NULL;
}

View File

@@ -15,18 +15,16 @@ IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxEvtHandler);
wxPyCallback::wxPyCallback(PyObject* func) {
m_func = func;
Py_INCREF(m_func);
wxPyBLOCK_THREADS( Py_INCREF(m_func) );
}
wxPyCallback::wxPyCallback(const wxPyCallback& other) {
m_func = other.m_func;
Py_INCREF(m_func);
wxPyBLOCK_THREADS( Py_INCREF(m_func) );
}
wxPyCallback::~wxPyCallback() {
wxPyBlock_t blocked = wxPyBeginBlockThreads();
Py_DECREF(m_func);
wxPyEndBlockThreads(blocked);
wxPyBLOCK_THREADS( Py_DECREF(m_func) );
}

View File

@@ -30,12 +30,12 @@
public:
wxPyEvtDict()
{
m_dict = PyDict_New();
wxPyBLOCK_THREADS(m_dict = PyDict_New());
}
wxPyEvtDict(const wxPyEvtDict& other)
{
m_dict = PyDict_Copy(other.m_dict);
wxPyBLOCK_THREADS(m_dict = PyDict_Copy(other.m_dict));
}
~wxPyEvtDict()
@@ -48,7 +48,7 @@
PyObject* _getAttrDict()
{
Py_INCREF(m_dict);
wxPyBLOCK_THREADS( Py_INCREF(m_dict) );
return m_dict;
}

View File

@@ -55,6 +55,7 @@ public:
wxPyInputStream(const wxPyInputStream& other)
{
wxPyBlock_t blocked = wxPyBeginBlockThreads();
m_read = other.m_read;
m_seek = other.m_seek;
m_tell = other.m_tell;
@@ -62,6 +63,7 @@ public:
Py_INCREF(m_read);
Py_INCREF(m_seek);
Py_INCREF(m_tell);
wxPyEndBlockThreads(blocked);
}
protected:

View File

@@ -55,6 +55,7 @@ public:
wxPyOutputStream(const wxPyOutputStream& other)
{
wxPyBlock_t blocked = wxPyBeginBlockThreads();
m_write = other.m_write;
m_seek = other.m_seek;
m_tell = other.m_tell;
@@ -62,6 +63,7 @@ public:
Py_INCREF(m_write);
Py_INCREF(m_seek);
Py_INCREF(m_tell);
wxPyEndBlockThreads(blocked);
}
protected:

View File

@@ -26,15 +26,14 @@
{
m_obj = obj;
m_incRef = incref;
if (incref)
Py_INCREF(m_obj);
if (incref) {
wxPyBLOCK_THREADS( Py_INCREF(m_obj) );
}
}
virtual ~wxPyUserData()
{
if (m_incRef) {
// TODO: wxPyBlock_t blocked = wxPyBeginBlockThreads();
Py_DECREF(m_obj);
//wxPyEndBlockThreads(blocked);
wxPyBLOCK_THREADS( Py_DECREF(m_obj) );
}
m_obj = NULL;
}
@@ -76,5 +75,8 @@
Py_INCREF(obj);
return obj;
%End
};
// NOTE TO SELF: It looks like the GIL is already held by the current thread
// in ConvertToTypeCode and ConvertFromTypeCode code blocks...

View File

@@ -14,43 +14,32 @@
%ModuleHeaderCode
// Convert a wxString to a Python string (actually a PyUnicode object).
// Assumes that the GIL has already been acquired.
inline PyObject* wx2PyString(const wxString& str) {
return PyUnicode_FromWideChar(str.wc_str(), str.length());
}
// Convert a PyObject to a wxString
// Assumes that the GIL has already been acquired.
wxString Py2wxString(PyObject* source);
// Raise NotImplemented exceptions
inline void wxPyRaiseNotImplemented() {
PyErr_SetNone(PyExc_NotImplementedError);
}
inline void wxPyRaiseNotImplementedMsg(const char* msg) {
PyErr_SetString(PyExc_NotImplementedError, msg);
}
typedef PyGILState_STATE wxPyBlock_t;
// Calls from Python to wxWindows code are wrapped in calls to these
// functions:
inline PyThreadState* wxPyBeginAllowThreads() {
PyThreadState* saved = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS;
PyThreadState* saved = PyEval_SaveThread(); // Like Py_BEGIN_ALLOW_THREADS;
return saved;
}
inline void wxPyEndAllowThreads(PyThreadState* saved) {
PyEval_RestoreThread(saved); // Py_END_ALLOW_THREADS;
PyEval_RestoreThread(saved); // Like Py_END_ALLOW_THREADS;
}
// Calls from wxWindows back to Python code, or even any PyObject
// manipulations, PyDECREF's and etc. are wrapped in calls to these functions:
inline wxPyBlock_t wxPyBeginBlockThreads() {
if (! Py_IsInitialized()) {
return (wxPyBlock_t)0;
@@ -59,7 +48,6 @@ inline wxPyBlock_t wxPyBeginBlockThreads() {
return state;
}
inline void wxPyEndBlockThreads(wxPyBlock_t blocked) {
if (! Py_IsInitialized()) {
return;
@@ -68,11 +56,6 @@ inline void wxPyEndBlockThreads(wxPyBlock_t blocked) {
}
PyObject* wxPyConstructObject(void* ptr,
const wxString& className,
int setThisOwn=0);
// A macro that will help to execute simple statments wrapped in
// StartBlock/EndBlockThreads calls
#define wxPyBLOCK_THREADS(stmt) \
@@ -82,6 +65,25 @@ PyObject* wxPyConstructObject(void* ptr,
#define wxPyErr_SetString(err, str) \
wxPyBLOCK_THREADS(PyErr_SetString(err, str))
// Raise NotImplemented exceptions
inline void wxPyRaiseNotImplemented() {
wxPyBLOCK_THREADS( PyErr_SetNone(PyExc_NotImplementedError) );
}
inline void wxPyRaiseNotImplementedMsg(const char* msg) {
wxPyBLOCK_THREADS( PyErr_SetString(PyExc_NotImplementedError, msg) );
}
// Create a PyObject of the requested type from a void* and a class name.
// Assumes that the GIL has already been acquired.
PyObject* wxPyConstructObject(void* ptr,
const wxString& className,
int setThisOwn=0);
%End
@@ -156,6 +158,7 @@ wxString Py2wxString(PyObject* source)
//}
// Create a PyObject of the requested type from a void* and a class name.
PyObject* wxPyConstructObject(void* ptr,
const wxString& className,
int setThisOwn)