Commit 2a2a530c authored by Dick Hollenbeck's avatar Dick Hollenbeck

improvements to python's GIL acquisition and release, but not done yet, since...

improvements to python's GIL acquisition and release, but not done yet, since I think the GIL needs to be acquired even when not involving wxPython.
parent a88d067a
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
#include <dialog_helpers.h> #include <dialog_helpers.h>
#include <convert_from_iu.h> #include <convert_from_iu.h>
#ifdef KICAD_SCRIPTING #if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
#include <python_scripting.h> #include <python_scripting.h>
#endif #endif
...@@ -410,7 +410,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title, ...@@ -410,7 +410,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) ); wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
#ifdef KICAD_SCRIPTING_WXPYTHON #ifdef KICAD_SCRIPTING_WXPYTHON
// Add the scripting panel // Add the scripting panel
EDA_PANEINFO pythonAuiInfo; EDA_PANEINFO pythonAuiInfo;
pythonAuiInfo.ScriptingToolbarPane(); pythonAuiInfo.ScriptingToolbarPane();
...@@ -424,8 +424,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title, ...@@ -424,8 +424,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
pythonAuiInfo.Name( wxT( "PythonPanel" ) ).Bottom().Layer(9) ); pythonAuiInfo.Name( wxT( "PythonPanel" ) ).Bottom().Layer(9) );
m_pythonPanelHidden = true; m_pythonPanelHidden = true;
#endif #endif
ReFillLayerWidget(); // this is near end because contents establish size ReFillLayerWidget(); // this is near end because contents establish size
......
...@@ -8,190 +8,190 @@ ...@@ -8,190 +8,190 @@
#include <stdio.h> #include <stdio.h>
PYTHON_FOOTPRINT_WIZARD::PYTHON_FOOTPRINT_WIZARD(PyObject *aWizard)
PYTHON_FOOTPRINT_WIZARD::PYTHON_FOOTPRINT_WIZARD( PyObject* aWizard )
{ {
PyLOCK lock;
this->m_PyWizard= aWizard; this->m_PyWizard= aWizard;
Py_XINCREF( aWizard ); Py_XINCREF( aWizard );
} }
PYTHON_FOOTPRINT_WIZARD::~PYTHON_FOOTPRINT_WIZARD() PYTHON_FOOTPRINT_WIZARD::~PYTHON_FOOTPRINT_WIZARD()
{ {
PyLOCK lock;
Py_XDECREF( this->m_PyWizard ); Py_XDECREF( this->m_PyWizard );
} }
PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod(const char* aMethod, PyObject *aArglist)
PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod( const char* aMethod, PyObject* aArglist )
{ {
PyObject *pFunc; PyLOCK lock;
/* pFunc is a new reference to the desired method */ // pFunc is a new reference to the desired method
pFunc = PyObject_GetAttrString( this->m_PyWizard, aMethod ); PyObject* pFunc = PyObject_GetAttrString( this->m_PyWizard, aMethod );
if ( pFunc && PyCallable_Check( pFunc ) ) if( pFunc && PyCallable_Check( pFunc ) )
{ {
PyObject *result; PyObject* result = PyObject_CallObject( pFunc, aArglist );
PY_BLOCK_THREADS( blocked );
result = PyObject_CallObject( pFunc, aArglist ); if( PyErr_Occurred() )
if ( PyErr_Occurred() )
{ {
PyObject *t, *v, *b; PyObject* t;
PyObject* v;
PyObject* b;
PyErr_Fetch( &t, &v, &b ); PyErr_Fetch( &t, &v, &b );
printf ( "calling %s()\n", aMethod ); printf ( "calling %s()\n", aMethod );
printf ( "Exception: %s\n", PyString_AsString( PyObject_Str(v) ) ); printf ( "Exception: %s\n", PyString_AsString( PyObject_Str( v ) ) );
printf ( " : %s\n", PyString_AsString( PyObject_Str(b) ) ); printf ( " : %s\n", PyString_AsString( PyObject_Str( b ) ) );
} }
PY_UNBLOCK_THREADS( blocked ); if( result )
if ( result )
{ {
Py_XDECREF( pFunc ); Py_XDECREF( pFunc );
return result; return result;
} }
} }
else else
{ {
printf( "method not found, or not callable: %s\n", aMethod ); printf( "method not found, or not callable: %s\n", aMethod );
} }
if ( pFunc ) if( pFunc )
Py_XDECREF( pFunc ); Py_XDECREF( pFunc );
return NULL; return NULL;
} }
wxString PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod( const char* aMethod, PyObject *aArglist )
wxString PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod( const char* aMethod, PyObject* aArglist )
{ {
wxString ret; wxString ret;
PyLOCK lock;
ret.Clear(); PyObject* result = CallMethod( aMethod, aArglist );
PyObject *result = CallMethod( aMethod, aArglist ); if( result )
if ( result )
{ {
PY_BLOCK_THREADS( blocked ); const char* str_res = PyString_AsString( result );
const char *str_res = PyString_AsString( result );
ret = wxString::FromUTF8( str_res ); ret = wxString::FromUTF8( str_res );
Py_DECREF( result ); Py_DECREF( result );
PY_UNBLOCK_THREADS( blocked );
} }
return ret; return ret;
} }
wxArrayString PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod wxArrayString PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod
( const char *aMethod, PyObject *aArglist ) ( const char* aMethod, PyObject* aArglist )
{ {
PyObject *result, *element;
wxArrayString ret; wxArrayString ret;
wxString str_item; wxString str_item;
PyLOCK lock;
result = CallMethod( aMethod, aArglist ); PyObject* result = CallMethod( aMethod, aArglist );
if ( result ) if( result )
{ {
if ( !PyList_Check(result) ) if( !PyList_Check( result ) )
{ {
Py_DECREF( result ); Py_DECREF( result );
ret.Add( wxT("PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod, result is not a list"), 1 ); ret.Add( wxT( "PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod, result is not a list" ), 1 );
return ret; return ret;
} }
PY_BLOCK_THREADS( blocked );
int list_size = PyList_Size( result ); int list_size = PyList_Size( result );
for ( int n=0; n<list_size; n++ ) for ( int n=0; n<list_size; n++ )
{ {
element = PyList_GetItem( result, n ); PyObject* element = PyList_GetItem( result, n );
const char* str_res = PyString_AsString( element );
const char *str_res = PyString_AsString( element );
str_item = wxString::FromUTF8( str_res ); str_item = wxString::FromUTF8( str_res );
ret.Add( str_item, 1 ); ret.Add( str_item, 1 );
} }
Py_DECREF( result ); Py_DECREF( result );
PY_UNBLOCK_THREADS( blocked );
} }
return ret; return ret;
} }
wxString PYTHON_FOOTPRINT_WIZARD::GetName() wxString PYTHON_FOOTPRINT_WIZARD::GetName()
{ {
PyLOCK lock;
return CallRetStrMethod( "GetName" ); return CallRetStrMethod( "GetName" );
} }
wxString PYTHON_FOOTPRINT_WIZARD::GetImage() wxString PYTHON_FOOTPRINT_WIZARD::GetImage()
{ {
PyLOCK lock;
return CallRetStrMethod( "GetImage" ); return CallRetStrMethod( "GetImage" );
} }
wxString PYTHON_FOOTPRINT_WIZARD::GetDescription() wxString PYTHON_FOOTPRINT_WIZARD::GetDescription()
{ {
PyLOCK lock;
return CallRetStrMethod( "GetDescription" ); return CallRetStrMethod( "GetDescription" );
} }
int PYTHON_FOOTPRINT_WIZARD::GetNumParameterPages() int PYTHON_FOOTPRINT_WIZARD::GetNumParameterPages()
{ {
int ret = 0; int ret = 0;
PyObject *result; PyLOCK lock;
/* Time to call the callback */ // Time to call the callback
result = CallMethod( "GetNumParameterPages" , NULL ); PyObject* result = CallMethod( "GetNumParameterPages" , NULL );
if (result) if( result )
{ {
if ( !PyInt_Check( result ) ) if( !PyInt_Check( result ) )
return -1; return -1;
PY_BLOCK_THREADS( blocked );
ret = PyInt_AsLong( result ); ret = PyInt_AsLong( result );
Py_DECREF( result ); Py_DECREF( result );
PY_UNBLOCK_THREADS( blocked );
} }
return ret; return ret;
} }
wxString PYTHON_FOOTPRINT_WIZARD::GetParameterPageName( int aPage ) wxString PYTHON_FOOTPRINT_WIZARD::GetParameterPageName( int aPage )
{ {
wxString ret; wxString ret;
PyObject *arglist; PyLOCK lock;
PyObject *result;
// Time to call the callback
PyObject* arglist = Py_BuildValue( "( i )", aPage );
PyObject* result = CallMethod( "GetParameterPageName", arglist );
/* Time to call the callback */
arglist = Py_BuildValue( "(i)", aPage );
result = CallMethod( "GetParameterPageName", arglist );
Py_DECREF( arglist ); Py_DECREF( arglist );
if ( result ) if( result )
{ {
PY_BLOCK_THREADS( blocked ); const char* str_res = PyString_AsString( result );
const char *str_res = PyString_AsString( result );
ret = wxString::FromUTF8( str_res ); ret = wxString::FromUTF8( str_res );
Py_DECREF( result ); Py_DECREF( result );
PY_UNBLOCK_THREADS( blocked );
} }
return ret; return ret;
} }
wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames( int aPage ) wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames( int aPage )
{ {
PyObject *arglist;
wxArrayString ret; wxArrayString ret;
PyLOCK lock;
arglist = Py_BuildValue( "(i)", aPage ); PyObject* arglist = Py_BuildValue( "( i )", aPage );
ret = CallRetArrayStrMethod( "GetParameterNames", arglist ); ret = CallRetArrayStrMethod( "GetParameterNames", arglist );
Py_DECREF( arglist ); Py_DECREF( arglist );
...@@ -199,53 +199,51 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames( int aPage ) ...@@ -199,53 +199,51 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames( int aPage )
{ {
wxString rest; wxString rest;
wxString item = ret[i]; wxString item = ret[i];
if ( item.StartsWith( wxT("*"), &rest ) ) if( item.StartsWith( wxT( "*" ), &rest ) )
{ {
ret[i]=rest; ret[i]=rest;
} }
} }
return ret; return ret;
} }
wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterTypes( int aPage ) wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterTypes( int aPage )
{ {
PyObject *arglist;
wxArrayString ret; wxArrayString ret;
PyLOCK lock;
arglist = Py_BuildValue( "(i)", aPage ); PyObject* arglist = Py_BuildValue( "( i )", aPage );
ret = CallRetArrayStrMethod( "GetParameterNames", arglist ); ret = CallRetArrayStrMethod( "GetParameterNames", arglist );
Py_DECREF(arglist); Py_DECREF( arglist );
for ( unsigned i=0; i<ret.GetCount(); i++ ) for ( unsigned i=0; i<ret.GetCount(); i++ )
{ {
wxString rest; wxString rest;
wxString item = ret[i]; wxString item = ret[i];
if ( item.StartsWith( wxT("*"), &rest ) ) if( item.StartsWith( wxT( "*" ), &rest ) )
{ {
ret[i]=wxT( "UNITS" ); /* units */ ret[i] = wxT( "UNITS" ); // units
} }
else else
{ {
ret[i]=wxT( "IU" ); /* internal units */ ret[i] = wxT( "IU" ); // internal units
} }
} }
return ret; return ret;
} }
wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterValues( int aPage ) wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterValues( int aPage )
{ {
PyObject *arglist; PyLOCK lock;
wxArrayString ret;
PyObject* arglist = Py_BuildValue( "( i )", aPage );
wxArrayString ret = CallRetArrayStrMethod( "GetParameterValues", arglist );
arglist = Py_BuildValue( "(i)", aPage );
ret = CallRetArrayStrMethod( "GetParameterValues", arglist );
Py_DECREF( arglist ); Py_DECREF( arglist );
return ret; return ret;
...@@ -253,83 +251,82 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterValues( int aPage ) ...@@ -253,83 +251,82 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterValues( int aPage )
wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterErrors( int aPage ) wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterErrors( int aPage )
{ {
PyObject *arglist; PyLOCK lock;
wxArrayString ret;
arglist = Py_BuildValue( "(i)", aPage ); PyObject* arglist = Py_BuildValue( "( i )", aPage );
ret = CallRetArrayStrMethod( "GetParameterErrors", arglist );
wxArrayString ret = CallRetArrayStrMethod( "GetParameterErrors", arglist );
Py_DECREF( arglist ); Py_DECREF( arglist );
return ret; return ret;
} }
wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues( int aPage, wxArrayString& aValues ) wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues( int aPage, wxArrayString& aValues )
{ {
int len = aValues.size(); int len = aValues.size();
PyObject *py_list;
py_list = PyList_New( len ); PyLOCK lock;
PyObject* py_list = PyList_New( len );
for ( int i=0; i<len ; i++ ) for ( int i=0; i<len ; i++ )
{ {
wxString str = aValues[i]; wxString str = aValues[i];
PyObject *py_str = PyString_FromString( (const char*)str.mb_str() ); PyObject* py_str = PyString_FromString( ( const char* )str.mb_str() );
PyList_SetItem( py_list, i, py_str ); PyList_SetItem( py_list, i, py_str );
} }
PyObject *arglist; PyObject* arglist;
arglist = Py_BuildValue( "(i,O)", aPage, py_list ); arglist = Py_BuildValue( "( i,O )", aPage, py_list );
wxString res = CallRetStrMethod( "SetParameterValues", arglist ); wxString res = CallRetStrMethod( "SetParameterValues", arglist );
Py_DECREF( arglist ); Py_DECREF( arglist );
return res; return res;
} }
/* this is a SWIG function declaration -from module.i*/
MODULE *PyModule_to_MODULE(PyObject *obj0);
MODULE *PYTHON_FOOTPRINT_WIZARD::GetModule() // this is a SWIG function declaration -from module.i
MODULE* PyModule_to_MODULE( PyObject* obj0 );
MODULE* PYTHON_FOOTPRINT_WIZARD::GetModule()
{ {
PyObject *result, *obj; PyLOCK lock;
result = CallMethod( "GetModule", NULL );
if (!result) PyObject* result = CallMethod( "GetModule", NULL );
return NULL;
PY_BLOCK_THREADS( blocked ); if( !result )
return NULL;
obj = PyObject_GetAttrString( result, "this" ); PyObject* obj = PyObject_GetAttrString( result, "this" );
if ( PyErr_Occurred() ) if( PyErr_Occurred() )
{ {
/* /*
PyObject *t, *v, *b; PyObject *t, *v, *b;
PyErr_Fetch(&t, &v, &b); PyErr_Fetch( &t, &v, &b );
printf ("calling GetModule()\n"); printf ( "calling GetModule()\n" );
printf ("Exception: %s\n",PyString_AsString(PyObject_Str(v))); printf ( "Exception: %s\n",PyString_AsString( PyObject_Str( v ) ) );
printf (" : %s\n",PyString_AsString(PyObject_Str(b))); printf ( " : %s\n",PyString_AsString( PyObject_Str( b ) ) );
*/ */
PyErr_Print(); PyErr_Print();
} }
PY_UNBLOCK_THREADS( blocked );
MODULE *mod = PyModule_to_MODULE( obj ); MODULE* mod = PyModule_to_MODULE( obj );
return mod; return mod;
} }
void PYTHON_FOOTPRINT_WIZARDS::register_wizard(PyObject* aPyWizard) void PYTHON_FOOTPRINT_WIZARDS::register_wizard( PyObject* aPyWizard )
{ {
PYTHON_FOOTPRINT_WIZARD *fw; PYTHON_FOOTPRINT_WIZARD* fw = new PYTHON_FOOTPRINT_WIZARD( aPyWizard );
fw = new PYTHON_FOOTPRINT_WIZARD( aPyWizard );
//printf( "Registered python footprint wizard '%s'\n", //printf( "Registered python footprint wizard '%s'\n",
// (const char*)fw->GetName().mb_str() // ( const char* )fw->GetName().mb_str()
// ); // );
// this get the wizard registered in the common // this get the wizard registered in the common
...@@ -338,17 +335,15 @@ void PYTHON_FOOTPRINT_WIZARDS::register_wizard(PyObject* aPyWizard) ...@@ -338,17 +335,15 @@ void PYTHON_FOOTPRINT_WIZARDS::register_wizard(PyObject* aPyWizard)
fw->register_wizard(); fw->register_wizard();
#if 0 #if 0
/* just to test if it works correctly */ // just to test if it works correctly
int pages = fw->GetNumParameterPages(); int pages = fw->GetNumParameterPages();
printf(" %d pages\n",pages); printf( " %d pages\n",pages );
for (int n=0; n<pages; n++) for ( int n=0; n<pages; n++ )
{ {
printf(" page %d->'%s'\n",n, printf( " page %d->'%s'\n",n,
(const char*)fw->GetParameterPageName(n).mb_str()); ( const char* )fw->GetParameterPageName( n ).mb_str() );
} }
#endif #endif
} }
...@@ -33,7 +33,7 @@ public: ...@@ -33,7 +33,7 @@ public:
wxArrayString GetParameterValues( int aPage ); wxArrayString GetParameterValues( int aPage );
wxArrayString GetParameterErrors( int aPage ); wxArrayString GetParameterErrors( int aPage );
wxString SetParameterValues( int aPage, wxArrayString& aValues ); //< must return "OK" or error description wxString SetParameterValues( int aPage, wxArrayString& aValues ); //< must return "OK" or error description
MODULE *GetModule(); MODULE* GetModule();
}; };
......
...@@ -126,11 +126,10 @@ static void swigSwitchPythonBuiltin() ...@@ -126,11 +126,10 @@ static void swigSwitchPythonBuiltin()
* *
*/ */
PyThreadState *g_PythonMainTState; PyThreadState* g_PythonMainTState;
bool pcbnewInitPythonScripting() bool pcbnewInitPythonScripting()
{ {
swigAddBuiltin(); // add builtin functions swigAddBuiltin(); // add builtin functions
swigAddModules(); // add our own modules swigAddModules(); // add our own modules
swigSwitchPythonBuiltin(); // switch the python builtin modules to our new list swigSwitchPythonBuiltin(); // switch the python builtin modules to our new list
...@@ -158,16 +157,18 @@ bool pcbnewInitPythonScripting() ...@@ -158,16 +157,18 @@ bool pcbnewInitPythonScripting()
// load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins // load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins
PY_BLOCK_THREADS( blocked );
#endif #endif
{
PyLOCK lock;
PyRun_SimpleString( "import sys\n" PyRun_SimpleString( "import sys\n"
"sys.path.append(\".\")\n" "sys.path.append(\".\")\n"
"import pcbnew\n" "import pcbnew\n"
"pcbnew.LoadPlugins()" "pcbnew.LoadPlugins()"
); );
}
PY_UNBLOCK_THREADS( blocked );
return true; return true;
} }
...@@ -180,7 +181,7 @@ void pcbnewFinishPythonScripting() ...@@ -180,7 +181,7 @@ void pcbnewFinishPythonScripting()
} }
#ifdef KICAD_SCRIPTING_WXPYTHON #if defined(KICAD_SCRIPTING_WXPYTHON)
void RedirectStdio() void RedirectStdio()
{ {
...@@ -193,9 +194,8 @@ import wx\n\ ...@@ -193,9 +194,8 @@ import wx\n\
output = wx.PyOnDemandOutputWindow()\n\ output = wx.PyOnDemandOutputWindow()\n\
c sys.stderr = output\n"; c sys.stderr = output\n";
PY_BLOCK_THREADS( blocked ); PyLOCK lock;
PyRun_SimpleString( python_redirect ); PyRun_SimpleString( python_redirect );
PY_UNBLOCK_THREADS( blocked );
} }
...@@ -228,7 +228,7 @@ def makeWindow(parent):\n\ ...@@ -228,7 +228,7 @@ def makeWindow(parent):\n\
PyObject* result; PyObject* result;
// As always, first grab the GIL // As always, first grab the GIL
PY_BLOCK_THREADS( blocked ); PyLOCK lock;
// Now make a dictionary to serve as the global namespace when the code is // Now make a dictionary to serve as the global namespace when the code is
// executed. Put a reference to the builtins module in it. // executed. Put a reference to the builtins module in it.
...@@ -245,7 +245,6 @@ def makeWindow(parent):\n\ ...@@ -245,7 +245,6 @@ def makeWindow(parent):\n\
if( !result ) if( !result )
{ {
PyErr_Print(); PyErr_Print();
PY_UNBLOCK_THREADS( blocked );
return NULL; return NULL;
} }
Py_DECREF(result); Py_DECREF(result);
...@@ -285,10 +284,6 @@ def makeWindow(parent):\n\ ...@@ -285,10 +284,6 @@ def makeWindow(parent):\n\
Py_DECREF( globals ); Py_DECREF( globals );
Py_DECREF( tuple ); Py_DECREF( tuple );
// Finally, after all Python stuff is done, release the GIL
PY_UNBLOCK_THREADS( blocked );
return window; return window;
} }
#endif #endif
...@@ -3,20 +3,19 @@ ...@@ -3,20 +3,19 @@
// undefs explained here: https://bugzilla.redhat.com/show_bug.cgi?id=427617 // undefs explained here: https://bugzilla.redhat.com/show_bug.cgi?id=427617
#ifdef _POSIX_C_SOURCE #ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE #undef _POSIX_C_SOURCE
#endif #endif
#ifdef _XOPEN_SOURCE #ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE #undef _XOPEN_SOURCE
#endif #endif
#include <Python.h> #include <Python.h>
#ifndef NO_WXPYTHON_EXTENSION_HEADERS #ifndef NO_WXPYTHON_EXTENSION_HEADERS
#ifdef KICAD_SCRIPTING_WXPYTHON #ifdef KICAD_SCRIPTING_WXPYTHON
#include <wx/wxPython/wxPython.h> #include <wx/wxPython/wxPython.h>
#endif #endif
#endif #endif
/* Function pcbnewInitPythonScripting /* Function pcbnewInitPythonScripting
* Initializes the Python engine inside pcbnew * Initializes the Python engine inside pcbnew
...@@ -26,20 +25,35 @@ bool pcbnewInitPythonScripting(); ...@@ -26,20 +25,35 @@ bool pcbnewInitPythonScripting();
void pcbnewFinishPythonScripting(); void pcbnewFinishPythonScripting();
#ifdef KICAD_SCRIPTING_WXPYTHON #ifdef KICAD_SCRIPTING_WXPYTHON
void RedirectStdio(); void RedirectStdio();
wxWindow* CreatePythonShellWindow(wxWindow* parent); wxWindow* CreatePythonShellWindow( wxWindow* parent );
class PyLOCK
{
wxPyBlock_t b;
public:
// @todo, find out why these are wxPython specific. We need the GIL regardless.
// Should never assume python will only have one thread calling it.
PyLOCK() { b = wxPyBeginBlockThreads(); }
~PyLOCK() { wxPyEndBlockThreads( b ); }
};
#define PY_BLOCK_THREADS(name) wxPyBlock_t name = wxPyBeginBlockThreads()
#define PY_UNBLOCK_THREADS(name) wxPyEndBlockThreads(name)
#else #else
#define PY_BLOCK_THREADS(name) class PyLOCK
#define PY_UNBLOCK_THREADS(name) {
public:
// @todo: this is wrong, python docs clearly say we need the GIL,
// irrespective of wxPython.
PyLOCK() {}
~PyLOCK() {}
};
#endif #endif
#endif #endif // __PYTHON_SCRIPTING_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment