aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py/source/py.cpp
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-01-09 04:59:30 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-01-09 04:59:30 +0000
commit53c16e06983f9b03464f41b8c0ed3206382c5538 (patch)
treed5a54d0c089ca1e622bfd605584922ae04580017 /externals/grill/py/source/py.cpp
parent66d28ea3c22decc8cc01d046f05dde113af16c70 (diff)
support for Python threads, at last
small fixes merged in 20041229-newdetach branch. renamed locking functions svn path=/trunk/; revision=2483
Diffstat (limited to 'externals/grill/py/source/py.cpp')
-rw-r--r--externals/grill/py/source/py.cpp174
1 files changed, 82 insertions, 92 deletions
diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp
index 021e710f..05aeea8d 100644
--- a/externals/grill/py/source/py.cpp
+++ b/externals/grill/py/source/py.cpp
@@ -2,7 +2,7 @@
py/pyext - python script object for PD and Max/MSP
-Copyright (c)2002-2004 Thomas Grill (gr@grrrr.org)
+Copyright (c)2002-2005 Thomas Grill (gr@grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
@@ -17,40 +17,43 @@ class pyobj:
FLEXT_HEADER_S(pyobj,py,Setup)
public:
- pyobj(I argc,const t_atom *argv);
+ pyobj(int argc,const t_atom *argv);
~pyobj();
protected:
- BL m_method_(I n,const t_symbol *s,I argc,const t_atom *argv);
+ bool m_method_(int n,const t_symbol *s,int argc,const t_atom *argv);
- BL work(const t_symbol *s,I argc,const t_atom *argv);
+ bool work(const t_symbol *s,int argc,const t_atom *argv);
- V m_bang() { callwork(sym_bang,0,NULL); }
- V m_reload();
- V m_reload_(I argc,const t_atom *argv);
- V m_set(I argc,const t_atom *argv);
- V m_dir_() { m__dir(function); }
- V m_doc_() { m__doc(function); }
+ void m_bang() { callwork(sym_bang,0,NULL); }
+ void m_reload();
+ void m_reload_(int argc,const t_atom *argv);
+ void m_set(int argc,const t_atom *argv);
+ void m_dir_() { m__dir(function); }
+ void m_doc_() { m__doc(function); }
- virtual V m_help();
+ virtual void m_help();
// methods for python arguments
- V callwork(const t_symbol *s,I argc,const t_atom *argv);
+ void callwork(const t_symbol *s,int argc,const t_atom *argv);
- V m_py_list(I argc,const t_atom *argv) { callwork(sym_list,argc,argv); }
- V m_py_float(I argc,const t_atom *argv) { callwork(sym_float,argc,argv); }
- V m_py_int(I argc,const t_atom *argv) { callwork(sym_int,argc,argv); }
- V m_py_any(const t_symbol *s,I argc,const t_atom *argv) { callwork(s,argc,argv); }
+ void m_py_list(int argc,const t_atom *argv) { callwork(sym_list,argc,argv); }
+ void m_py_float(int argc,const t_atom *argv) { callwork(sym_float,argc,argv); }
+ void m_py_int(int argc,const t_atom *argv) { callwork(sym_int,argc,argv); }
+ void m_py_any(const t_symbol *s,int argc,const t_atom *argv) { callwork(s,argc,argv); }
const t_symbol *funname;
PyObject *function;
- virtual V Reload();
+ virtual void Reload();
- V SetFunction(const C *func);
- V ResetFunction();
+ void SetFunction(const char *func);
+ void ResetFunction();
private:
+
+ virtual bool callpy(PyObject *fun,PyObject *args);
+
static void Setup(t_classid c);
FLEXT_CALLBACK(m_bang)
@@ -98,10 +101,10 @@ void pyobj::Setup(t_classid c)
FLEXT_CADDATTR_VAR1(c,"respond",respond);
}
-pyobj::pyobj(I argc,const t_atom *argv):
+pyobj::pyobj(int argc,const t_atom *argv):
function(NULL),funname(NULL)
{
- PY_LOCK
+ PyThreadState *state = PyLock();
AddInAnything(2);
AddOutAnything();
@@ -116,7 +119,7 @@ pyobj::pyobj(I argc,const t_atom *argv):
if(!IsString(argv[0]))
post("%s - script name argument is invalid",thisName());
else {
- C dir[1024];
+ char dir[1024];
GetModulePath(GetString(argv[0]),dir,sizeof(dir));
// set script path
AddToPath(dir);
@@ -127,12 +130,11 @@ pyobj::pyobj(I argc,const t_atom *argv):
// add current dir to path
AddToPath(GetString(canvas_getcurrentdir()));
#elif FLEXT_SYS == FLEXT_SYS_MAX
-#if FLEXT_OS == FLEXT_OS_WIN
-#else
+/*
short path = patcher_myvol(thisCanvas());
path_topathname(path,NULL,dir);
AddToPath(dir);
-#endif
+*/
#else
#pragma message("Adding current dir to path is not implemented")
#endif
@@ -153,29 +155,29 @@ pyobj::pyobj(I argc,const t_atom *argv):
}
}
- PY_UNLOCK
+ PyUnlock(state);
}
pyobj::~pyobj()
{
- PY_LOCK
+ PyThreadState *state = PyLock();
Unregister("_py");
- PY_UNLOCK
+ PyUnlock(state);
}
-BL pyobj::m_method_(I n,const t_symbol *s,I argc,const t_atom *argv)
+bool pyobj::m_method_(int n,const t_symbol *s,int argc,const t_atom *argv)
{
if(n == 1)
post("%s - no method for type %s",thisName(),GetString(s));
return false;
}
-V pyobj::m_reload()
+void pyobj::m_reload()
{
- PY_LOCK
+ PyThreadState *state = PyLock();
Unregister("_py");
@@ -184,29 +186,29 @@ V pyobj::m_reload()
Register("_py");
SetFunction(funname?GetString(funname):NULL);
- PY_UNLOCK
+ PyUnlock(state);
}
-V pyobj::m_reload_(I argc,const t_atom *argv)
+void pyobj::m_reload_(int argc,const t_atom *argv)
{
- PY_LOCK
+ PyThreadState *state = PyLock();
SetArgs(argc,argv);
- PY_UNLOCK
+ PyUnlock(state);
m_reload();
}
-V pyobj::m_set(I argc,const t_atom *argv)
+void pyobj::m_set(int argc,const t_atom *argv)
{
- PY_LOCK
+ PyThreadState *state = PyLock();
- I ix = 0;
+ int ix = 0;
if(argc >= 2) {
if(!IsString(argv[ix])) {
post("%s - script name is not valid",thisName());
return;
}
- const C *sn = GetString(argv[ix]);
+ const char *sn = GetString(argv[ix]);
if(!module || !strcmp(sn,PyModule_GetName(module))) {
ImportModule(sn);
@@ -221,13 +223,13 @@ V pyobj::m_set(I argc,const t_atom *argv)
else
SetFunction(GetString(argv[ix]));
- PY_UNLOCK
+ PyUnlock(state);
}
-V pyobj::m_help()
+void pyobj::m_help()
{
post("");
- post("%s %s - python script object, (C)2002-2004 Thomas Grill",thisName(),PY__VERSION);
+ post("%s %s - python script object, (C)2002-2005 Thomas Grill",thisName(),PY__VERSION);
#ifdef FLEXT_DEBUG
post("DEBUG VERSION, compiled on " __DATE__ " " __TIME__);
#endif
@@ -248,13 +250,13 @@ V pyobj::m_help()
post("\tdir: dump module dictionary");
post("\tdir+: dump function dictionary");
#ifdef FLEXT_THREADS
- post("\tdetach 0/1: detach threads");
+ post("\tdetach 0/1/2: detach threads");
post("\tstop {wait time (ms)}: stop threads");
#endif
post("");
}
-V pyobj::ResetFunction()
+void pyobj::ResetFunction()
{
if(!module || !dict)
{
@@ -263,7 +265,7 @@ V pyobj::ResetFunction()
return;
}
- function = funname?PyDict_GetItemString(dict,(C *)GetString(funname)):NULL; // borrowed!!!
+ function = funname?PyDict_GetItemString(dict,(char *)GetString(funname)):NULL; // borrowed!!!
if(!function) {
PyErr_Clear();
if(funname) post("%s - Function %s could not be found",thisName(),GetString(funname));
@@ -274,7 +276,7 @@ V pyobj::ResetFunction()
}
}
-V pyobj::SetFunction(const C *func)
+void pyobj::SetFunction(const char *func)
{
if(func) {
funname = MakeSymbol(func);
@@ -285,63 +287,51 @@ V pyobj::SetFunction(const C *func)
}
-V pyobj::Reload()
+void pyobj::Reload()
{
ResetFunction();
}
-
-BL pyobj::work(const t_symbol *s,I argc,const t_atom *argv)
+bool pyobj::callpy(PyObject *fun,PyObject *args)
{
- AtomList *rargs = NULL;
- BL ret;
-
- ++thrcount;
- PY_LOCK
+ PyObject *ret = PyObject_Call(fun,args,NULL);
+ if(ret == NULL) {
+ // function not found resp. arguments not matching
+ PyErr_Print();
+ return false;
+ }
+ else {
+ AtomList *rargs = GetPyArgs(ret);
+ if(!rargs)
+ PyErr_Print();
+ else {
+ // call to outlet _outside_ the Mutex lock!
+ // otherwise (if not detached) deadlock will occur
+ if(rargs->Count()) ToOutList(0,*rargs);
+ delete rargs;
+ }
+ Py_DECREF(ret);
+ return true;
+ }
+}
+void pyobj::callwork(const t_symbol *s,int argc,const t_atom *argv)
+{
+ bool ret = false;
+
if(function) {
- PyObject *pArgs = MakePyArgs(s,argc,argv);
- PyObject *pValue = PyObject_CallObject(function, pArgs);
-
- rargs = GetPyArgs(pValue);
- if(!rargs) PyErr_Print();
-
- Py_XDECREF(pArgs);
- Py_XDECREF(pValue);
- ret = true;
- }
+ PyThreadState *state = PyLock();
+
+ PyObject *pargs = MakePyArgs(s,argc,argv);
+ Py_INCREF(function);
+ ret = gencall(function,pargs);
+
+ PyUnlock(state);
+ }
else {
post("%s: no function defined",thisName());
ret = false;
}
- PY_UNLOCK
- --thrcount;
-
- if(rargs) {
- // call to outlet _outside_ the Mutex lock!
- // otherwise (if not detached) deadlock will occur
- if(rargs->Count()) ToOutList(0,*rargs);
- delete rargs;
- }
-
- return ret;
-}
-
-V pyobj::callwork(const t_symbol *s,I argc,const t_atom *argv)
-{
- BL ret = false;
- if(detach) {
- if(shouldexit)
- post("%s - New threads can't be launched now!",thisName());
- else {
- ret = FLEXT_CALLMETHOD_A(work,s,argc,argv);
- if(!ret) post("%s - Failed to launch thread!",thisName());
- }
- }
- else
- ret = work(s,argc,argv);
Respond(ret);
}
-
-