aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-03-08 04:59:25 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-03-08 04:59:25 +0000
commit0bd834874c00c5fc5ed251c9fdbff68608d44eb5 (patch)
treea427b34472a5d4976bbee3b3d083ce432bdb80b1
parentdfcbb9904402efc8f0deec2a16bd905b911da0aa (diff)
pass timeout argument to stop method
fixes for detached mode fixes for detached operation and single-threaded version use lock count instead of message queuing to avoid py->py messaging deadlock use new flext fifo svn path=/trunk/; revision=2602
-rw-r--r--externals/grill/py/source/clmeth.cpp7
-rw-r--r--externals/grill/py/source/main.cpp48
-rw-r--r--externals/grill/py/source/main.h23
-rw-r--r--externals/grill/py/source/modmeth.cpp6
4 files changed, 55 insertions, 29 deletions
diff --git a/externals/grill/py/source/clmeth.cpp b/externals/grill/py/source/clmeth.cpp
index 489b7dc5..6062eda9 100644
--- a/externals/grill/py/source/clmeth.cpp
+++ b/externals/grill/py/source/clmeth.cpp
@@ -113,6 +113,7 @@ PyObject* pyext::pyext_getattr(PyObject *,PyObject *args)
ERRINTERNAL();
}
+#ifdef FLEXT_THREADS
if(PyString_Check(name)) {
char* sname = PyString_AS_STRING(name);
if(sname) {
@@ -124,6 +125,7 @@ PyObject* pyext::pyext_getattr(PyObject *,PyObject *args)
// post("pyext::getattr %s",sname);
}
}
+#endif
if(!ret) {
#if PY_VERSION_HEX >= 0x02020000
@@ -231,9 +233,10 @@ PyObject *pyext::pyext_stop(PyObject *,PyObject *args)
}
else {
pyext *ext = GetThis(self);
- int cnt = 0;
+ int cnt;
t_atom at;
- if(val >= 0) flext::SetInt(at,val);
+ if(val >= 0) cnt = 1,flext::SetInt(at,val);
+ else cnt = 0;
ext->m_stop(cnt,&at);
}
diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp
index feabfde1..01dc0afa 100644
--- a/externals/grill/py/source/main.cpp
+++ b/externals/grill/py/source/main.cpp
@@ -157,18 +157,19 @@ void py::Setup(t_classid c)
#endif
}
-py::py():
- module(NULL),
- detach(0),shouldexit(false),thrcount(0),
- stoptick(0)
+py::py()
+ : module(NULL),detach(0)
+#ifdef FLEXT_THREADS
+ , shouldexit(false),thrcount(0),stoptick(0)
+#endif
{
PyThreadState *state = PyLock();
Py_INCREF(module_obj);
PyUnlock(state);
+#ifdef FLEXT_THREADS
FLEXT_ADDTIMER(stoptmr,tick);
-#ifdef FLEXT_THREADS
// launch thread worker
FLEXT_CALLMETHOD(threadworker);
#endif
@@ -176,27 +177,29 @@ py::py():
py::~py()
{
- shouldexit = true;
+ PyThreadState *state = PyLock();
+ Py_XDECREF(module_obj);
+ PyUnlock(state);
+}
+void py::Exit()
+{
#ifdef FLEXT_THREADS
+ shouldexit = true;
qucond.Signal();
-
if(thrcount) {
// Wait for a certain time
- for(int i = 0; i < (PY_STOP_WAIT/PY_STOP_TICK) && thrcount; ++i) Sleep((float)(PY_STOP_TICK/1000.));
+ for(int i = 0; i < (PY_STOP_WAIT/PY_STOP_TICK) && thrcount; ++i) Sleep(PY_STOP_TICK/1000.f);
// Wait forever
post("%s - Waiting for thread termination!",thisName());
- while(thrcount) Sleep(0.01f);
+ while(thrcount) Sleep(PY_STOP_TICK/1000.f);
post("%s - Okay, all threads have terminated",thisName());
}
#endif
- PyThreadState *state = PyLock();
- Py_XDECREF(module_obj);
- PyUnlock(state);
+ flext_base::Exit();
}
-
void py::GetDir(PyObject *obj,AtomList &lst)
{
if(obj) {
@@ -475,7 +478,6 @@ bool py::gencall(PyObject *pmeth,PyObject *pargs)
// put call into queue
ret = qucall(pmeth,pargs);
break;
-#endif
case 2:
// each call a new thread
if(!shouldexit) {
@@ -483,8 +485,9 @@ bool py::gencall(PyObject *pmeth,PyObject *pargs)
if(!ret) post("%s - Failed to launch thread!",thisName());
}
break;
+#endif
default:
- FLEXT_ASSERT(false);
+ post("%s - Unknown detach mode",thisName());
}
return ret;
}
@@ -493,7 +496,9 @@ void py::work_wrapper(void *data)
{
FLEXT_ASSERT(data);
+#ifdef FLEXT_THREADS
++thrcount;
+#endif
PyThreadState *state = PyLock();
@@ -504,7 +509,9 @@ void py::work_wrapper(void *data)
PyUnlock(state);
+#ifdef FLEXT_THREADS
--thrcount;
+#endif
}
#ifdef FLEXT_THREADS
@@ -522,16 +529,22 @@ void py::threadworker()
FifoEl *el;
PyThreadState *state;
- while(!shouldexit) {
+ ++thrcount;
+ for(;;) {
while(el = qufifo.Get()) {
+ ++thrcount;
state = PyLock();
callpy(el->fun,el->args);
Py_XDECREF(el->fun);
Py_XDECREF(el->args);
PyUnlock(state);
qufifo.Free(el);
+ --thrcount;
}
- qucond.Wait();
+ if(shouldexit)
+ break;
+ else
+ qucond.Wait();
}
state = PyLock();
@@ -542,6 +555,7 @@ void py::threadworker()
qufifo.Free(el);
}
PyUnlock(state);
+ --thrcount;
}
#endif
diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h
index cd1c3736..2d495461 100644
--- a/externals/grill/py/source/main.h
+++ b/externals/grill/py/source/main.h
@@ -25,8 +25,8 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#define PYEXT_MODULE "pyext" // name for module
#define PYEXT_CLASS "_class" // name for base class
-#define PY_STOP_WAIT 1000 // ms
-#define PY_STOP_TICK 10 // ms
+#define PY_STOP_WAIT 100 // ms
+#define PY_STOP_TICK 1 // ms
@@ -50,6 +50,8 @@ public:
~py();
static void lib_setup();
+ virtual void Exit();
+
static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet = -1,bool withself = false);
static AtomList *GetPyArgs(PyObject *pValue,PyObject **self = NULL);
@@ -109,14 +111,18 @@ protected:
virtual void m_stop(int argc,const t_atom *argv);
- bool shouldexit,respond;
+ bool respond;
+#ifdef FLEXT_THREADS
+ bool shouldexit;
int thrcount;
int stoptick;
Timer stoptmr;
- int detach;
void tick(void *);
-
+#endif
+
+ int detach;
+
bool gencall(PyObject *fun,PyObject *args);
virtual bool callpy(PyObject *fun,PyObject *args) = 0;
@@ -153,18 +159,19 @@ public:
// this is respecially needed when one py/pyext object calls another one
// we don't want the message to be queued, but otoh we have to avoid deadlock
+ // (recursive calls can only happen in the system thread)
static int lockcount;
inline PyThreadState *PyLock()
{
- if(!lockcount++) PyEval_AcquireLock();
+ if(!IsSystemThread() || !lockcount++) PyEval_AcquireLock();
return PyThreadState_Swap(FindThreadState());
}
inline void PyUnlock(PyThreadState *st)
{
PyThreadState_Swap(st);
- if(!--lockcount) PyEval_ReleaseLock();
+ if(!IsSystemThread() || !--lockcount) PyEval_ReleaseLock();
}
#else
inline void Lock() {}
@@ -189,9 +196,9 @@ protected:
FLEXT_CALLBACK(m_dir)
FLEXT_CALLGET_V(mg_dir)
FLEXT_CALLBACK(m_doc)
- FLEXT_CALLBACK_T(tick)
#ifdef FLEXT_THREADS
+ FLEXT_CALLBACK_T(tick)
FLEXT_THREAD(threadworker)
#endif
};
diff --git a/externals/grill/py/source/modmeth.cpp b/externals/grill/py/source/modmeth.cpp
index cf4dca88..70eb536a 100644
--- a/externals/grill/py/source/modmeth.cpp
+++ b/externals/grill/py/source/modmeth.cpp
@@ -45,7 +45,7 @@ const char *py::py_doc =
;
-
+#ifdef FLEXT_THREADS
void py::tick(void *)
{
Lock();
@@ -68,9 +68,11 @@ void py::tick(void *)
Unlock();
}
+#endif
void py::m_stop(int argc,const t_atom *argv)
{
+#ifdef FLEXT_THREADS
if(thrcount) {
Lock();
@@ -89,7 +91,7 @@ void py::m_stop(int argc,const t_atom *argv)
Unlock();
}
-
+#endif
}
PyObject *py::py_samplerate(PyObject *self,PyObject *args)