aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py
diff options
context:
space:
mode:
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);
-}