mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-06 03:50:06 +01:00
Add and use the wxPyThreadBlocker class.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@71603 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -39,6 +39,11 @@ def run():
|
||||
tools.fixWindowClass(c)
|
||||
module.addGlobalStr('wxAnimationCtrlNameStr', c)
|
||||
|
||||
# move this before wxAnimationCtrl so it can be used for default arg values
|
||||
item = module.find('wxNullAnimation')
|
||||
module.items.remove(item)
|
||||
module.insertItemBefore(c, item)
|
||||
|
||||
|
||||
# TODO: It would be nice to be able to use the generic verison on all
|
||||
# platforms since the native GTK version has some limitations...
|
||||
|
||||
@@ -224,12 +224,11 @@ def run():
|
||||
body="""\
|
||||
wxBitmap* bmp = new wxBitmap(width, height, 24);
|
||||
wxPyCopyBitmapFromBuffer(bmp, (byte*)data->m_ptr, data->m_len, wxBitmapBufferFormat_RGB);
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
if (PyErr_Occurred()) {
|
||||
delete bmp;
|
||||
bmp = NULL;
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return bmp;
|
||||
""")
|
||||
|
||||
@@ -267,12 +266,11 @@ def run():
|
||||
body="""\
|
||||
wxBitmap* bmp = new wxBitmap(width, height, 32);
|
||||
wxPyCopyBitmapFromBuffer(bmp, (byte*)data->m_ptr, data->m_len, wxBitmapBufferFormat_RGBA);
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
if (PyErr_Occurred()) {
|
||||
delete bmp;
|
||||
bmp = NULL;
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return bmp;
|
||||
""")
|
||||
|
||||
|
||||
@@ -67,23 +67,20 @@ def run():
|
||||
# holding the data...
|
||||
c.addCppMethod('PyObject*', 'GetPrivData', '()', """\
|
||||
PyObject* data;
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
data = PyBytes_FromStringAndSize(self->GetPrivData(),
|
||||
self->GetPrivDataLen());
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return data;
|
||||
""")
|
||||
|
||||
c.addCppMethod('void', 'SetPrivData', '(PyObject* data)', """\
|
||||
wxPyThreadBlocker blocker;
|
||||
if (! PyBytes_Check(data)) {
|
||||
wxPyBLOCK_THREADS(PyErr_SetString(PyExc_TypeError,
|
||||
"Expected string object"));
|
||||
return /* NULL */ ;
|
||||
wxPyErr_SetString(PyExc_TypeError, "Expected string object");
|
||||
return;
|
||||
}
|
||||
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
self->SetPrivData(PyBytes_AS_STRING(data), PyBytes_GET_SIZE(data));
|
||||
wxPyEndBlockThreads(blocked);
|
||||
""")
|
||||
|
||||
c.addAutoProperties()
|
||||
|
||||
@@ -50,14 +50,13 @@ def addGetAllFormats(klass, pureVirtual=False):
|
||||
size_t count = self->GetFormatCount(dir);
|
||||
wxDataFormat* formats = new wxDataFormat[count];
|
||||
self->GetAllFormats(formats, dir);
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* list = PyList_New(count);
|
||||
for (size_t i=0; i<count; i++) {
|
||||
wxDataFormat* format = new wxDataFormat(formats[i]);
|
||||
PyObject* obj = wxPyConstructObject((void*)format, wxT("wxDataFormat"), true);
|
||||
PyList_SET_ITEM(list, i, obj); // PyList_SET_ITEM steals a reference
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
delete [] formats;
|
||||
return list;
|
||||
""",
|
||||
|
||||
@@ -205,10 +205,6 @@ def run():
|
||||
(entry->m_callbackUserData != NULL))
|
||||
{
|
||||
wxPyCallback *cb = (wxPyCallback*)entry->m_callbackUserData;
|
||||
//wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
//int result = PyObject_Compare(cb->m_func, func);
|
||||
//wxPyEndBlockThreads(blocked);
|
||||
//if (result == 0) {
|
||||
if (cb->m_func == func) {
|
||||
delete cb;
|
||||
self->GetDynamicEventTable()->Erase(node);
|
||||
@@ -458,18 +454,16 @@ def run():
|
||||
c.find('GetFiles').setCppCode("""\
|
||||
int count = self->GetNumberOfFiles();
|
||||
wxString* files = self->GetFiles();
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* list = PyList_New(count);
|
||||
if (!list) {
|
||||
PyErr_SetString(PyExc_MemoryError, "Can't allocate list of files!");
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return NULL;
|
||||
}
|
||||
for (int i=0; i<count; i++) {
|
||||
PyObject* s = wx2PyString(files[i]);
|
||||
PyList_SET_ITEM(list, i, s);
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return list;
|
||||
""")
|
||||
|
||||
|
||||
14
etg/image.py
14
etg/image.py
@@ -228,11 +228,8 @@ def run():
|
||||
byte* data = self->GetData();
|
||||
Py_ssize_t len = self->GetWidth() * self->GetHeight() * 3;
|
||||
PyObject* rv;
|
||||
Py_buffer view;
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
PyBuffer_FillInfo(&view, NULL, data, len, 0, PyBUF_WRITABLE|PyBUF_FORMAT|PyBUF_ND);
|
||||
rv = PyMemoryView_FromBuffer(&view);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
wxPyThreadBlocker blocker;
|
||||
rv = wxPyMakeBuffer(data, len);
|
||||
return rv;
|
||||
""")
|
||||
|
||||
@@ -245,11 +242,8 @@ def run():
|
||||
byte* data = self->GetAlpha();
|
||||
Py_ssize_t len = self->GetWidth() * self->GetHeight();
|
||||
PyObject* rv;
|
||||
Py_buffer view;
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
PyBuffer_FillInfo(&view, NULL, data, len, 0, PyBUF_WRITABLE|PyBUF_FORMAT|PyBUF_ND);
|
||||
rv = PyMemoryView_FromBuffer(&view);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
wxPyThreadBlocker blocker;
|
||||
rv = wxPyMakeBuffer(data, len);
|
||||
return rv;
|
||||
""")
|
||||
|
||||
|
||||
@@ -37,10 +37,8 @@ def run():
|
||||
class wxJoystick : public wxObject {
|
||||
public:
|
||||
wxJoystick(int joystick = wxJOYSTICK1) {
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
PyErr_SetString(PyExc_NotImplementedError,
|
||||
"wxJoystick is not available on this platform.");
|
||||
wxPyEndBlockThreads(blocked);
|
||||
wxPyErr_SetString(PyExc_NotImplementedError,
|
||||
"wxJoystick is not available on this platform.");
|
||||
}
|
||||
wxPoint GetPosition() const { return wxPoint(-1,-1); }
|
||||
int GetPosition(unsigned axis) const { return -1; }
|
||||
|
||||
@@ -67,7 +67,7 @@ def run():
|
||||
{
|
||||
int retval = 0;
|
||||
PyObject* func = (PyObject*)funcPtr;
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
|
||||
PyObject* args = Py_BuildValue("(ii)", item1, item2);
|
||||
PyObject* result = PyEval_CallObject(func, args);
|
||||
@@ -77,7 +77,6 @@ def run():
|
||||
Py_DECREF(result);
|
||||
}
|
||||
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return retval;
|
||||
}
|
||||
""")
|
||||
|
||||
@@ -111,7 +111,7 @@ def run():
|
||||
static PyObject* _makeReadBufObj(wxInputStream* self, wxMemoryBuffer& buf) {
|
||||
PyObject* obj = NULL;
|
||||
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
wxStreamError err = self->GetLastError(); // error check
|
||||
if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) {
|
||||
PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
|
||||
@@ -120,7 +120,6 @@ def run():
|
||||
// Return the data as a string object. TODO: Py3
|
||||
obj = PyBytes_FromStringAndSize(buf, buf.GetDataLen());
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return obj;
|
||||
}
|
||||
""")
|
||||
|
||||
@@ -74,7 +74,7 @@ def run():
|
||||
doc='Returns a list of currently selected items in the tree. This function '
|
||||
'can be called only if the control has the wx.TR_MULTIPLE style.',
|
||||
body="""\
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* rval = PyList_New(0);
|
||||
wxArrayTreeItemIds array;
|
||||
size_t num, x;
|
||||
@@ -85,7 +85,6 @@ def run():
|
||||
PyList_Append(rval, item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return rval;
|
||||
""")
|
||||
|
||||
@@ -104,10 +103,9 @@ def run():
|
||||
body="""\
|
||||
wxRect rect;
|
||||
if (self->GetBoundingRect(*item, rect, textOnly)) {
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
wxRect* r = new wxRect(rect);
|
||||
PyObject* val = wxPyConstructObject((void*)r, wxT("wxRect"), true);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return val;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -83,7 +83,6 @@ def nci(text, numSpaces=0, stripLeading=True):
|
||||
# io.StringIO reads/writes unicode objects for both Python 2.7 and 3.x. For
|
||||
# 2.7 we'll convert any string values to unicode objects before storing them
|
||||
# in the StringIO
|
||||
|
||||
import io
|
||||
class Utf8EncodingStream(io.StringIO):
|
||||
if sys.version_info < (3,):
|
||||
|
||||
@@ -867,7 +867,7 @@ static
|
||||
{{
|
||||
{objType}* array;
|
||||
Py_ssize_t idx, len;
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
|
||||
// ensure that it is a sequence
|
||||
if (! PySequence_Check(source))
|
||||
@@ -893,7 +893,6 @@ 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++) {{
|
||||
@@ -906,12 +905,10 @@ 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())
|
||||
|
||||
@@ -152,11 +152,10 @@ void wxPyApp::OnAssertFailure(const wxChar *file,
|
||||
buf << wxT(": ") << msg;
|
||||
|
||||
// set the exception
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* s = wx2PyString(buf);
|
||||
PyErr_SetObject(wxAssertionError, s);
|
||||
Py_DECREF(s);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
|
||||
// Now when control returns to whatever API wrapper was called from
|
||||
// Python it should detect that an exception is set and will return
|
||||
@@ -187,7 +186,6 @@ void wxPyApp::_BootstrapApp()
|
||||
{
|
||||
static bool haveInitialized = false;
|
||||
bool result;
|
||||
wxPyBlock_t blocked;
|
||||
|
||||
// Only initialize wxWidgets once
|
||||
if (! haveInitialized) {
|
||||
@@ -201,29 +199,29 @@ void wxPyApp::_BootstrapApp()
|
||||
#endif
|
||||
int argc = 0;
|
||||
argType** argv = NULL;
|
||||
blocked = wxPyBeginBlockThreads();
|
||||
PyObject* sysargv = PySys_GetObject("argv");
|
||||
if (sysargv != NULL) {
|
||||
argc = PyList_Size(sysargv);
|
||||
argv = new argType*[argc+1];
|
||||
int x;
|
||||
for(x=0; x<argc; x++) {
|
||||
PyObject *pyArg = PyList_GetItem(sysargv, x); // borrowed reference
|
||||
// if there isn't anything in sys.argv[0] then set it to the python executable
|
||||
if (x == 0 && PyObject_Length(pyArg) < 1)
|
||||
pyArg = PySys_GetObject("executable");
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
int len = PyObject_Length(pyArg);
|
||||
argv[x] = new argType[len+1];
|
||||
wxPyUnicode_AsWideChar(pyArg, argv[x], len+1);
|
||||
#else
|
||||
argv[x] = strdup(PyBytes_AsString(pyArg));
|
||||
#endif
|
||||
{
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* sysargv = PySys_GetObject("argv");
|
||||
if (sysargv != NULL) {
|
||||
argc = PyList_Size(sysargv);
|
||||
argv = new argType*[argc+1];
|
||||
int x;
|
||||
for(x=0; x<argc; x++) {
|
||||
PyObject *pyArg = PyList_GetItem(sysargv, x); // borrowed reference
|
||||
// if there isn't anything in sys.argv[0] then set it to the python executable
|
||||
if (x == 0 && PyObject_Length(pyArg) < 1)
|
||||
pyArg = PySys_GetObject("executable");
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
int len = PyObject_Length(pyArg);
|
||||
argv[x] = new argType[len+1];
|
||||
wxPyUnicode_AsWideChar(pyArg, argv[x], len+1);
|
||||
#else
|
||||
argv[x] = strdup(PyBytes_AsString(pyArg));
|
||||
#endif
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
|
||||
|
||||
// Initialize wxWidgets
|
||||
#ifdef __WXOSX__
|
||||
@@ -232,17 +230,15 @@ void wxPyApp::_BootstrapApp()
|
||||
result = wxEntryStart(argc, argv);
|
||||
// wxApp takes ownership of the argv array, don't delete it here
|
||||
|
||||
blocked = wxPyBeginBlockThreads();
|
||||
if (! result) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"wxEntryStart failed, unable to initialize wxWidgets!"
|
||||
wxPyErr_SetString(PyExc_SystemError,
|
||||
"wxEntryStart failed, unable to initialize wxWidgets!"
|
||||
#ifdef __WXGTK__
|
||||
" (Is DISPLAY set properly?)"
|
||||
" (Is DISPLAY set properly?)"
|
||||
#endif
|
||||
);
|
||||
goto error;
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
haveInitialized = true;
|
||||
}
|
||||
else {
|
||||
@@ -256,12 +252,11 @@ void wxPyApp::_BootstrapApp()
|
||||
OnPreInit();
|
||||
result = OnInit();
|
||||
|
||||
blocked = wxPyBeginBlockThreads();
|
||||
if (! result) {
|
||||
PyErr_SetString(PyExc_SystemExit, "OnInit returned false, exiting...");
|
||||
wxPyErr_SetString(PyExc_SystemExit, "OnInit returned false, exiting...");
|
||||
}
|
||||
error:
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ void wxPyCallback::EventThunker(wxEvent& event) {
|
||||
PyObject* tuple;
|
||||
bool checkSkip = false;
|
||||
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
wxString className = event.GetClassInfo()->GetClassName();
|
||||
arg = wxPyConstructObject((void*)&event, className);
|
||||
|
||||
@@ -59,5 +59,4 @@ void wxPyCallback::EventThunker(wxEvent& event) {
|
||||
}
|
||||
Py_DECREF(tuple);
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
@@ -40,10 +40,9 @@
|
||||
|
||||
~wxPyEvtDict()
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
Py_DECREF(m_dict);
|
||||
m_dict = NULL;
|
||||
wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
PyObject* _getAttrDict()
|
||||
@@ -55,7 +54,7 @@
|
||||
PyObject* __getattr__(PyObject* name)
|
||||
{
|
||||
PyObject* value = NULL;
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
if (PyDict_Contains(m_dict, name)) {
|
||||
value = PyDict_GetItem(m_dict, name);
|
||||
Py_INCREF(value);
|
||||
@@ -63,25 +62,22 @@
|
||||
else {
|
||||
PyErr_SetObject(PyExc_AttributeError, name);
|
||||
}
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return value;
|
||||
}
|
||||
|
||||
void __setattr__(PyObject* name, PyObject* value)
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyDict_SetItem(m_dict, name, value);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
void __delattr__(PyObject* name)
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
if (PyDict_Contains(m_dict, name))
|
||||
PyDict_DelItem(m_dict, name);
|
||||
else
|
||||
PyErr_SetObject(PyExc_AttributeError, name);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -33,29 +33,24 @@ public:
|
||||
wxPyInputStream(PyObject* fileObj, bool block=true)
|
||||
{
|
||||
m_block = block;
|
||||
wxPyBlock_t blocked = wxPyBlock_t_default;
|
||||
if (block) blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker(m_block);
|
||||
|
||||
m_read = wxPyGetMethod(fileObj, "read");
|
||||
m_seek = wxPyGetMethod(fileObj, "seek");
|
||||
m_tell = wxPyGetMethod(fileObj, "tell");
|
||||
|
||||
if (block) wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
virtual ~wxPyInputStream()
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBlock_t_default;
|
||||
if (m_block) blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker(m_block);
|
||||
Py_XDECREF(m_read);
|
||||
Py_XDECREF(m_seek);
|
||||
Py_XDECREF(m_tell);
|
||||
if (m_block) wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
wxPyInputStream(const wxPyInputStream& other)
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
m_read = other.m_read;
|
||||
m_seek = other.m_seek;
|
||||
m_tell = other.m_tell;
|
||||
@@ -63,7 +58,6 @@ public:
|
||||
Py_INCREF(m_read);
|
||||
Py_INCREF(m_seek);
|
||||
Py_INCREF(m_tell);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -88,7 +82,7 @@ protected:
|
||||
if (bufsize == 0)
|
||||
return 0;
|
||||
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* arglist = Py_BuildValue("(i)", bufsize);
|
||||
PyObject* result = PyEval_CallObject(m_read, arglist);
|
||||
Py_DECREF(arglist);
|
||||
@@ -106,7 +100,6 @@ protected:
|
||||
}
|
||||
else
|
||||
m_lasterror = wxSTREAM_READ_ERROR;
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -118,7 +111,7 @@ protected:
|
||||
|
||||
wxFileOffset OnSysSeek(wxFileOffset off, wxSeekMode mode)
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* arglist = PyTuple_New(2);
|
||||
|
||||
if (sizeof(wxFileOffset) > sizeof(long))
|
||||
@@ -133,13 +126,12 @@ protected:
|
||||
PyObject* result = PyEval_CallObject(m_seek, arglist);
|
||||
Py_DECREF(arglist);
|
||||
Py_XDECREF(result);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return OnSysTell();
|
||||
}
|
||||
|
||||
wxFileOffset OnSysTell() const
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* arglist = Py_BuildValue("()");
|
||||
PyObject* result = PyEval_CallObject(m_tell, arglist);
|
||||
Py_DECREF(arglist);
|
||||
@@ -151,7 +143,6 @@ protected:
|
||||
o = wxPyInt_AsLong(result);
|
||||
Py_DECREF(result);
|
||||
};
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,29 +33,24 @@ public:
|
||||
wxPyOutputStream(PyObject* fileObj, bool block=true)
|
||||
{
|
||||
m_block = block;
|
||||
wxPyBlock_t blocked = wxPyBlock_t_default;
|
||||
if (block) blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker(m_block);
|
||||
|
||||
m_write = wxPyGetMethod(fileObj, "write");
|
||||
m_seek = wxPyGetMethod(fileObj, "seek");
|
||||
m_tell = wxPyGetMethod(fileObj, "tell");
|
||||
|
||||
if (block) wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
virtual ~wxPyOutputStream()
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBlock_t_default;
|
||||
if (m_block) blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker(m_block);
|
||||
Py_XDECREF(m_write);
|
||||
Py_XDECREF(m_seek);
|
||||
Py_XDECREF(m_tell);
|
||||
if (m_block) wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
wxPyOutputStream(const wxPyOutputStream& other)
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
m_write = other.m_write;
|
||||
m_seek = other.m_seek;
|
||||
m_tell = other.m_tell;
|
||||
@@ -63,7 +58,6 @@ public:
|
||||
Py_INCREF(m_write);
|
||||
Py_INCREF(m_seek);
|
||||
Py_INCREF(m_tell);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -94,7 +88,7 @@ protected:
|
||||
if (bufsize == 0)
|
||||
return 0;
|
||||
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* arglist = PyTuple_New(1);
|
||||
PyTuple_SET_ITEM(arglist, 0, PyBytes_FromStringAndSize((char*)buffer, bufsize));
|
||||
|
||||
@@ -105,13 +99,12 @@ protected:
|
||||
Py_DECREF(result);
|
||||
else
|
||||
m_lasterror = wxSTREAM_WRITE_ERROR;
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
wxFileOffset OnSysSeek(wxFileOffset off, wxSeekMode mode)
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* arglist = PyTuple_New(2);
|
||||
|
||||
if (sizeof(wxFileOffset) > sizeof(long))
|
||||
@@ -126,13 +119,12 @@ protected:
|
||||
PyObject* result = PyEval_CallObject(m_seek, arglist);
|
||||
Py_DECREF(arglist);
|
||||
Py_XDECREF(result);
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return OnSysTell();
|
||||
}
|
||||
|
||||
wxFileOffset OnSysTell() const
|
||||
{
|
||||
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||
wxPyThreadBlocker blocker;
|
||||
PyObject* arglist = Py_BuildValue("()");
|
||||
PyObject* result = PyEval_CallObject(m_tell, arglist);
|
||||
Py_DECREF(arglist);
|
||||
@@ -144,7 +136,6 @@ protected:
|
||||
o = wxPyInt_AsLong(result);
|
||||
Py_DECREF(result);
|
||||
};
|
||||
wxPyEndBlockThreads(blocked);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
|
||||
%ConvertFromTypeCode
|
||||
// Code to convert a wxClientData back to the PyObject.
|
||||
// Code to convert a wxPyUserData back to the PyObject.
|
||||
PyObject* obj;
|
||||
if (sipCpp == NULL) {
|
||||
obj = Py_None;
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
typedef PyGILState_STATE wxPyBlock_t;
|
||||
#define wxPyBlock_t_default PyGILState_UNLOCKED
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned char* buffer;
|
||||
|
||||
@@ -74,7 +76,7 @@ inline void wxPyEndAllowThreads(PyThreadState* saved) {
|
||||
// A macro that will help to execute simple statments wrapped in
|
||||
// StartBlock/EndBlockThreads calls
|
||||
#define wxPyBLOCK_THREADS(stmt) \
|
||||
{ wxPyBlock_t blocked = wxPyBeginBlockThreads(); stmt; wxPyEndBlockThreads(blocked); }
|
||||
{ wxPyThreadBlocker _blocker; stmt; }
|
||||
|
||||
// Raise any exception with a string value (blocking threads)
|
||||
#define wxPyErr_SetString(err, str) \
|
||||
@@ -96,6 +98,7 @@ inline void wxPyEndAllowThreads(PyThreadState* saved) {
|
||||
|
||||
|
||||
inline PyObject* wxPyMakeBuffer(void* ptr, Py_ssize_t len) {
|
||||
// GIL should already be held
|
||||
Py_buffer view;
|
||||
PyBuffer_FillInfo(&view, NULL, ptr, len, 0, PyBUF_WRITABLE|PyBUF_FORMAT|PyBUF_ND);
|
||||
return PyMemoryView_FromBuffer(&view);
|
||||
@@ -123,6 +126,7 @@ inline PyObject* wxPyMakeBuffer(void* ptr, Py_ssize_t len) {
|
||||
inline
|
||||
Py_ssize_t wxPyUnicode_AsWideChar(PyObject* unicode, wchar_t* w, Py_ssize_t size)
|
||||
{
|
||||
// GIL should already be held
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return PyUnicode_AsWideChar(unicode, w, size);
|
||||
#else
|
||||
@@ -162,7 +166,7 @@ inline wxPyAPI* wxPyGetAPIPtr()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Inline wrappers to call the API functions
|
||||
// Inline wrappers which call the functions in the API structure
|
||||
|
||||
// Convert a PyObject to a wxString
|
||||
// Assumes that the GIL has already been acquired.
|
||||
@@ -184,4 +188,30 @@ inline wxPyBlock_t wxPyBeginBlockThreads()
|
||||
inline void wxPyEndBlockThreads(wxPyBlock_t blocked)
|
||||
{ wxPyGetAPIPtr()->p_wxPyEndBlockThreads(blocked); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Convenience helper for RAII thread blocking
|
||||
class wxPyThreadBlocker {
|
||||
public:
|
||||
explicit wxPyThreadBlocker(bool block=true)
|
||||
: m_oldstate(block ? wxPyBeginBlockThreads() : wxPyBlock_t_default),
|
||||
m_block(block)
|
||||
{ }
|
||||
|
||||
~wxPyThreadBlocker() {
|
||||
if (m_block) {
|
||||
wxPyEndBlockThreads(m_oldstate);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void operator=(const wxPyThreadBlocker&);
|
||||
explicit wxPyThreadBlocker(const wxPyThreadBlocker&);
|
||||
wxPyBlock_t m_oldstate;
|
||||
bool m_block;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user