aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-07-19 13:18:33 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-07-19 13:18:33 +0000
commit8994dac676a881dce818238d4519182a8bf635ea (patch)
tree4ff2fe3c64fcf70b6e62f3fa72a719177228db9a /externals/grill/py
parentad51a5256a81891061f4c1cc729c718029beb128 (diff)
better exception handling and error message
much better detach method handling (one thread for all object instances) oops, forgot to code one branch better definition of output values (atoms, lists, anythings) svn path=/trunk/; revision=3360
Diffstat (limited to 'externals/grill/py')
-rw-r--r--externals/grill/py/readme.txt1
-rw-r--r--externals/grill/py/source/main.h5
-rw-r--r--externals/grill/py/source/py.cpp14
-rw-r--r--externals/grill/py/source/pyargs.cpp5
-rw-r--r--externals/grill/py/source/pybase.cpp75
-rw-r--r--externals/grill/py/source/pybase.h15
-rw-r--r--externals/grill/py/source/pyext.cpp9
-rw-r--r--externals/grill/py/source/pyext.h5
-rw-r--r--externals/grill/py/source/pymeth.cpp14
9 files changed, 70 insertions, 73 deletions
diff --git a/externals/grill/py/readme.txt b/externals/grill/py/readme.txt
index 9213786d..0c4bc0f4 100644
--- a/externals/grill/py/readme.txt
+++ b/externals/grill/py/readme.txt
@@ -98,6 +98,7 @@ Version history:
- FIX: cleanup for outbound messages (e.g. symbol atoms instead of one-element general messages)
- FIX: better exception handling (no longer leaves reference to function object) and cleared misleading error message
- FIX: better definition of output values for atoms, lists and anythings
+- FIX: much better detached method handling (one thread for all object instances!)
0.2.0:
- ADD: handling of Python threads
diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h
index 479c082d..86098b4c 100644
--- a/externals/grill/py/source/main.h
+++ b/externals/grill/py/source/main.h
@@ -25,11 +25,14 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#define PY_STOP_TICK 1 // ms
+class pybase;
+
class FifoEl
: public Fifo::Cell
{
public:
- void Set(PyObject *f,PyObject *a) { fun = f,args = a; }
+ void Set(pybase *t,PyObject *f,PyObject *a) { th = t,fun = f,args = a; }
+ pybase *th;
PyObject *fun,*args;
};
diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp
index 4b7c2bdc..b4b4f225 100644
--- a/externals/grill/py/source/py.cpp
+++ b/externals/grill/py/source/py.cpp
@@ -47,7 +47,6 @@ protected:
bool SetFunction(const t_symbol *func);
bool ResetFunction();
- virtual bool thrcall(void *data);
virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv);
PyObject **objects;
@@ -77,10 +76,6 @@ private:
#ifdef FLEXT_THREADS
FLEXT_CALLBACK_T(tick)
- FLEXT_THREAD(threadworker)
- FLEXT_THREAD_X(work_wrapper)
-#else
- FLEXT_CALLBACK_X(work_wrapper)
#endif
};
@@ -104,7 +99,7 @@ void pyobj::Setup(t_classid c)
FLEXT_CADDMETHOD_(c,0,"set",m_set);
- FLEXT_CADDATTR_VAR1(c,"xlate",xlate);
+ FLEXT_CADDATTR_VAR1(c,"py",xlate);
FLEXT_CADDATTR_VAR1(c,"respond",respond);
}
@@ -116,8 +111,6 @@ pyobj::pyobj(int argc,const t_atom *argv)
{
#ifdef FLEXT_THREADS
FLEXT_ADDTIMER(stoptmr,tick);
- // launch thread worker
- FLEXT_CALLMETHOD(threadworker);
#endif
PyThreadState *state = PyLockSys();
@@ -426,8 +419,3 @@ void pyobj::DumpOut(const t_symbol *sym,int argc,const t_atom *argv)
{
ToOutAnything(GetOutAttr(),sym?sym:thisTag(),argc,argv);
}
-
-bool pyobj::thrcall(void *data)
-{
- return FLEXT_CALLMETHOD_X(work_wrapper,data);
-}
diff --git a/externals/grill/py/source/pyargs.cpp b/externals/grill/py/source/pyargs.cpp
index 2cdfdade..d631903b 100644
--- a/externals/grill/py/source/pyargs.cpp
+++ b/externals/grill/py/source/pyargs.cpp
@@ -192,6 +192,11 @@ const t_symbol *pybase::GetPyArgs(AtomList &lst,PyObject *pValue,int offs)
getlist(lst.Atoms(),l,rargc);
sym = pyObject_AsSymbol(s);
}
+ else {
+ // (symbol,atom) list
+ lst(offs+rargc);
+ sym = getlist(lst.Atoms(),pValue,rargc);
+ }
Py_DECREF(s);
Py_DECREF(l);
diff --git a/externals/grill/py/source/pybase.cpp b/externals/grill/py/source/pybase.cpp
index 65c4369d..20f16e13 100644
--- a/externals/grill/py/source/pybase.cpp
+++ b/externals/grill/py/source/pybase.cpp
@@ -56,6 +56,9 @@ void pybase::FreeThreadState()
pythrmap.erase(it);
}
}
+
+PyFifo pybase::qufifo;
+flext::ThrCond pybase::qucond;
#endif
@@ -167,6 +170,9 @@ void pybase::lib_setup()
#ifdef FLEXT_THREADS
// release global lock
PyEval_ReleaseLock();
+
+ // launch thread worker
+ LaunchThread(quworker,NULL);
#endif
post("------------------------------------------------");
@@ -182,7 +188,8 @@ FLEXT_LIB_SETUP(py,pybase::lib_setup)
pybase::pybase()
: module(NULL)
#ifdef FLEXT_THREADS
- , shouldexit(false),thrcount(0),stoptick(0)
+ , thrcount(0)
+ , shouldexit(false),stoptick(0)
#endif
, detach(0)
, xlate(true)
@@ -202,8 +209,11 @@ pybase::~pybase()
void pybase::Exit()
{
#ifdef FLEXT_THREADS
+ erasethreads();
+
shouldexit = true;
qucond.Signal();
+
if(thrcount) {
// Wait for a certain time
for(int i = 0; i < (PY_STOP_WAIT/PY_STOP_TICK) && thrcount; ++i)
@@ -580,7 +590,10 @@ bool pybase::gencall(PyObject *pmeth,PyObject *pargs)
case 2:
// each call a new thread
if(!shouldexit) {
- ret = thrcall(new work_data(pmeth,pargs));
+ thr_params *p = new thr_params;
+ p->cl = (flext_base *)this;
+ p->var->_ext = new work_data(pmeth,pargs);
+ ret = LaunchThread(thrworker,p);
if(!ret) post("py/pyext - Failed to launch thread!");
}
break;
@@ -609,62 +622,54 @@ void pybase::exchandle()
#endif
}
-void pybase::work_wrapper(void *data)
-{
- FLEXT_ASSERT(data);
-
#ifdef FLEXT_THREADS
- ++thrcount;
-#endif
+void pybase::thrworker(thr_params *p)
+{
+ FLEXT_ASSERT(p);
+ pybase *th = (pybase *)p->cl;
+ work_data *w = (work_data *)p->var->_ext;
+ ++th->thrcount; // \todo this should be atomic
PyThreadState *state = PyLock();
// call worker
- work_data *w = (work_data *)data;
- docall(w->fun,w->args);
+ th->docall(w->fun,w->args);
delete w;
PyUnlock(state);
-
-#ifdef FLEXT_THREADS
- --thrcount;
-#endif
+ --th->thrcount; // \todo this should be atomic
}
-#ifdef FLEXT_THREADS
bool pybase::qucall(PyObject *fun,PyObject *args)
{
FifoEl *el = qufifo.New();
- el->Set(fun,args);
+ el->Set(this,fun,args);
qufifo.Put(el);
qucond.Signal();
return true;
}
-void pybase::threadworker()
+void pybase::quworker(thr_params *)
{
- ++thrcount;
-
FifoEl *el;
PyThreadState *my = FindThreadState(),*state;
for(;;) {
while(el = qufifo.Get()) {
- ++thrcount;
+ ++el->th->thrcount; // \todo this should be atomic
state = PyLock(my);
- docall(el->fun,el->args);
+ el->th->docall(el->fun,el->args);
Py_XDECREF(el->fun);
Py_XDECREF(el->args);
PyUnlock(state);
+ --el->th->thrcount; // \todo this should be atomic
qufifo.Free(el);
- --thrcount;
}
- if(shouldexit)
- break;
- else
- qucond.Wait();
+ qucond.Wait();
}
+ // we never end
+#if 0
state = PyLock(my);
// unref remaining Python objects
while(el = qufifo.Get()) {
@@ -673,8 +678,24 @@ void pybase::threadworker()
qufifo.Free(el);
}
PyUnlock(state);
+#endif
+}
- --thrcount;
+void pybase::erasethreads()
+{
+ PyFifo tmp;
+ FifoEl *el;
+ while(el = qufifo.Get()) {
+ if(el->th == this) {
+ Py_XDECREF(el->fun);
+ Py_XDECREF(el->args);
+ qufifo.Free(el);
+ }
+ else
+ tmp.Put(el);
+ }
+ // Push back
+ while(el = tmp.Get()) qufifo.Put(el);
}
#endif
diff --git a/externals/grill/py/source/pybase.h b/externals/grill/py/source/pybase.h
index f7b6840b..28ee9770 100644
--- a/externals/grill/py/source/pybase.h
+++ b/externals/grill/py/source/pybase.h
@@ -148,7 +148,7 @@ protected:
return true;
}
- virtual bool thrcall(void *data) = 0;
+// virtual bool thrcall(void *data) = 0;
virtual void callpy(PyObject *fun,PyObject *args) = 0;
void exchandle();
@@ -161,13 +161,16 @@ protected:
protected:
- void work_wrapper(void *data);
-
#ifdef FLEXT_THREADS
+ static void thrworker(thr_params *data);
+
bool qucall(PyObject *fun,PyObject *args);
- void threadworker();
- PyFifo qufifo;
- ThrCond qucond;
+
+ static void quworker(thr_params *);
+ void erasethreads();
+
+ static PyFifo qufifo;
+ static ThrCond qucond;
static PyThreadState *pythrsys;
static PyThreadState *FindThreadState();
diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp
index a48a45ed..4252e64a 100644
--- a/externals/grill/py/source/pyext.cpp
+++ b/externals/grill/py/source/pyext.cpp
@@ -41,7 +41,7 @@ void pyext::Setup(t_classid c)
FLEXT_CADDMETHOD_(c,0,"get",m_get);
FLEXT_CADDMETHOD_(c,0,"set",m_set);
- FLEXT_CADDATTR_VAR1(c,"xlate",xlate);
+ FLEXT_CADDATTR_VAR1(c,"py",xlate);
FLEXT_CADDATTR_VAR1(c,"respond",respond);
// ----------------------------------------------------
@@ -120,8 +120,6 @@ pyext::pyext(int argc,const t_atom *argv,bool sig):
{
#ifdef FLEXT_THREADS
FLEXT_ADDTIMER(stoptmr,tick);
- // launch thread worker
- FLEXT_CALLMETHOD(threadworker);
#endif
if(argc >= 2 && CanbeInt(argv[0]) && CanbeInt(argv[1])) {
@@ -629,8 +627,3 @@ void pyext::DumpOut(const t_symbol *sym,int argc,const t_atom *argv)
{
ToOutAnything(GetOutAttr(),sym?sym:thisTag(),argc,argv);
}
-
-bool pyext::thrcall(void *data)
-{
- return FLEXT_CALLMETHOD_X(work_wrapper,data);
-}
diff --git a/externals/grill/py/source/pyext.h b/externals/grill/py/source/pyext.h
index 361eda5d..d4652409 100644
--- a/externals/grill/py/source/pyext.h
+++ b/externals/grill/py/source/pyext.h
@@ -113,7 +113,6 @@ private:
bool call(const char *meth,int inlet,const t_symbol *s,int argc,const t_atom *argv);
- virtual bool thrcall(void *data);
virtual void callpy(PyObject *fun,PyObject *args);
static bool stcallpy(PyObject *fun,PyObject *args);
@@ -148,10 +147,6 @@ private:
#ifdef FLEXT_THREADS
FLEXT_CALLBACK_T(tick)
- FLEXT_THREAD(threadworker)
- FLEXT_THREAD_X(work_wrapper)
-#else
- FLEXT_CALLBACK_X(work_wrapper)
#endif
};
diff --git a/externals/grill/py/source/pymeth.cpp b/externals/grill/py/source/pymeth.cpp
index e2278d1c..399c9463 100644
--- a/externals/grill/py/source/pymeth.cpp
+++ b/externals/grill/py/source/pymeth.cpp
@@ -124,7 +124,6 @@ protected:
void SetFunction(const t_symbol *func);
void ResetFunction();
- virtual bool thrcall(void *data);
virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv);
PyObject **objects;
@@ -154,10 +153,6 @@ private:
#ifdef FLEXT_THREADS
FLEXT_CALLBACK_T(tick)
- FLEXT_THREAD(threadworker)
- FLEXT_THREAD_X(work_wrapper)
-#else
- FLEXT_CALLBACK_X(work_wrapper)
#endif
};
@@ -181,7 +176,7 @@ void pymeth::Setup(t_classid c)
FLEXT_CADDMETHOD_(c,0,"set",m_set);
- FLEXT_CADDATTR_VAR1(c,"xlate",xlate);
+ FLEXT_CADDATTR_VAR1(c,"py",xlate);
FLEXT_CADDATTR_VAR1(c,"respond",respond);
// init translation map
@@ -195,8 +190,6 @@ pymeth::pymeth(int argc,const t_atom *argv)
{
#ifdef FLEXT_THREADS
FLEXT_ADDTIMER(stoptmr,tick);
- // launch thread worker
- FLEXT_CALLMETHOD(threadworker);
#endif
PyThreadState *state = PyLockSys();
@@ -436,8 +429,3 @@ void pymeth::DumpOut(const t_symbol *sym,int argc,const t_atom *argv)
{
ToOutAnything(GetOutAttr(),sym?sym:thisTag(),argc,argv);
}
-
-bool pymeth::thrcall(void *data)
-{
- return FLEXT_CALLMETHOD_X(work_wrapper,data);
-}