diff options
author | Thomas Grill <xovo@users.sourceforge.net> | 2005-01-09 04:59:30 +0000 |
---|---|---|
committer | Thomas Grill <xovo@users.sourceforge.net> | 2005-01-09 04:59:30 +0000 |
commit | 53c16e06983f9b03464f41b8c0ed3206382c5538 (patch) | |
tree | d5a54d0c089ca1e622bfd605584922ae04580017 /externals/grill/py/source/py.cpp | |
parent | 66d28ea3c22decc8cc01d046f05dde113af16c70 (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.cpp | 174 |
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); } - - |