Update of /cvsroot/pure-data/externals/grill/py/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8086/source
Modified Files: clmeth.cpp main.cpp main.h modmeth.cpp Log Message: 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
Index: modmeth.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/modmeth.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** modmeth.cpp 11 Jan 2005 04:59:27 -0000 1.14 --- modmeth.cpp 8 Mar 2005 04:59:25 -0000 1.15 *************** *** 46,50 ****
! void py::tick(void *) { --- 46,50 ----
! #ifdef FLEXT_THREADS void py::tick(void *) { *************** *** 69,75 **** --- 69,77 ---- Unlock(); } + #endif
void py::m_stop(int argc,const t_atom *argv) { + #ifdef FLEXT_THREADS if(thrcount) { Lock(); *************** *** 90,94 **** Unlock(); } ! }
--- 92,96 ---- Unlock(); } ! #endif }
Index: clmeth.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** clmeth.cpp 27 Feb 2005 04:57:30 -0000 1.14 --- clmeth.cpp 8 Mar 2005 04:59:23 -0000 1.15 *************** *** 114,117 **** --- 114,118 ---- }
+ #ifdef FLEXT_THREADS if(PyString_Check(name)) { char* sname = PyString_AS_STRING(name); *************** *** 125,128 **** --- 126,130 ---- } } + #endif
if(!ret) { *************** *** 232,238 **** else { pyext *ext = GetThis(self); ! int cnt = 0; t_atom at; ! if(val >= 0) flext::SetInt(at,val); ext->m_stop(cnt,&at); } --- 234,241 ---- else { pyext *ext = GetThis(self); ! int cnt; t_atom at; ! if(val >= 0) cnt = 1,flext::SetInt(at,val); ! else cnt = 0; ext->m_stop(cnt,&at); }
Index: main.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/main.cpp,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** main.cpp 6 Mar 2005 04:57:32 -0000 1.26 --- main.cpp 8 Mar 2005 04:59:25 -0000 1.27 *************** *** 158,165 **** }
! py::py(): ! module(NULL), ! detach(0),shouldexit(false),thrcount(0), ! stoptick(0) { PyThreadState *state = PyLock(); --- 158,166 ---- }
! py::py() ! : module(NULL),detach(0) ! #ifdef FLEXT_THREADS ! , shouldexit(false),thrcount(0),stoptick(0) ! #endif { PyThreadState *state = PyLock(); *************** *** 167,173 **** PyUnlock(state);
FLEXT_ADDTIMER(stoptmr,tick);
- #ifdef FLEXT_THREADS // launch thread worker FLEXT_CALLMETHOD(threadworker); --- 168,174 ---- PyUnlock(state);
+ #ifdef FLEXT_THREADS FLEXT_ADDTIMER(stoptmr,tick);
// launch thread worker FLEXT_CALLMETHOD(threadworker); *************** *** 177,201 **** py::~py() { ! shouldexit = true;
#ifdef FLEXT_THREADS 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.));
// Wait forever post("%s - Waiting for thread termination!",thisName()); ! while(thrcount) Sleep(0.01f); post("%s - Okay, all threads have terminated",thisName()); } #endif ! PyThreadState *state = PyLock(); ! Py_XDECREF(module_obj); ! PyUnlock(state); }
- void py::GetDir(PyObject *obj,AtomList &lst) { --- 178,204 ---- py::~py() { ! 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(PY_STOP_TICK/1000.f);
// Wait forever post("%s - Waiting for thread termination!",thisName()); ! while(thrcount) Sleep(PY_STOP_TICK/1000.f); post("%s - Okay, all threads have terminated",thisName()); } #endif ! flext_base::Exit(); }
void py::GetDir(PyObject *obj,AtomList &lst) { *************** *** 476,480 **** ret = qucall(pmeth,pargs); break; - #endif case 2: // each call a new thread --- 479,482 ---- *************** *** 484,489 **** } break; default: ! FLEXT_ASSERT(false); } return ret; --- 486,492 ---- } break; + #endif default: ! post("%s - Unknown detach mode",thisName()); } return ret; *************** *** 494,498 **** --- 497,503 ---- FLEXT_ASSERT(data);
+ #ifdef FLEXT_THREADS ++thrcount; + #endif
PyThreadState *state = PyLock(); *************** *** 505,509 **** --- 510,516 ---- PyUnlock(state);
+ #ifdef FLEXT_THREADS --thrcount; + #endif }
*************** *** 523,528 **** PyThreadState *state;
! while(!shouldexit) { while(el = qufifo.Get()) { state = PyLock(); callpy(el->fun,el->args); --- 530,537 ---- PyThreadState *state;
! ++thrcount; ! for(;;) { while(el = qufifo.Get()) { + ++thrcount; state = PyLock(); callpy(el->fun,el->args); *************** *** 531,536 **** PyUnlock(state); qufifo.Free(el); } ! qucond.Wait(); }
--- 540,549 ---- PyUnlock(state); qufifo.Free(el); + --thrcount; } ! if(shouldexit) ! break; ! else ! qucond.Wait(); }
*************** *** 543,546 **** --- 556,560 ---- } PyUnlock(state); + --thrcount; } #endif
Index: main.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/main.h,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** main.h 6 Mar 2005 04:57:32 -0000 1.33 --- main.h 8 Mar 2005 04:59:25 -0000 1.34 *************** *** 26,31 **** #define PYEXT_CLASS "_class" // name for base class
! #define PY_STOP_WAIT 1000 // ms ! #define PY_STOP_TICK 10 // ms
--- 26,31 ---- #define PYEXT_CLASS "_class" // name for base class
! #define PY_STOP_WAIT 100 // ms ! #define PY_STOP_TICK 1 // ms
*************** *** 51,54 **** --- 51,56 ---- 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); *************** *** 110,121 **** virtual void m_stop(int argc,const t_atom *argv);
! bool shouldexit,respond; int thrcount; int stoptick; Timer stoptmr; - int detach;
void tick(void *); ! bool gencall(PyObject *fun,PyObject *args); virtual bool callpy(PyObject *fun,PyObject *args) = 0; --- 112,127 ---- virtual void m_stop(int argc,const t_atom *argv);
! bool respond; ! #ifdef FLEXT_THREADS ! bool shouldexit; int thrcount; int stoptick; Timer stoptmr;
void tick(void *); ! #endif ! ! int detach; ! bool gencall(PyObject *fun,PyObject *args); virtual bool callpy(PyObject *fun,PyObject *args) = 0; *************** *** 154,162 **** // 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 static int lockcount;
inline PyThreadState *PyLock() { ! if(!lockcount++) PyEval_AcquireLock(); return PyThreadState_Swap(FindThreadState()); } --- 160,169 ---- // 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(!IsSystemThread() || !lockcount++) PyEval_AcquireLock(); return PyThreadState_Swap(FindThreadState()); } *************** *** 165,169 **** { PyThreadState_Swap(st); ! if(!--lockcount) PyEval_ReleaseLock(); } #else --- 172,176 ---- { PyThreadState_Swap(st); ! if(!IsSystemThread() || !--lockcount) PyEval_ReleaseLock(); } #else *************** *** 190,196 **** FLEXT_CALLGET_V(mg_dir) FLEXT_CALLBACK(m_doc) - FLEXT_CALLBACK_T(tick)
#ifdef FLEXT_THREADS FLEXT_THREAD(threadworker) #endif --- 197,203 ---- FLEXT_CALLGET_V(mg_dir) FLEXT_CALLBACK(m_doc)
#ifdef FLEXT_THREADS + FLEXT_CALLBACK_T(tick) FLEXT_THREAD(threadworker) #endif