diff options
author | Thomas Grill <xovo@users.sourceforge.net> | 2003-06-14 02:32:39 +0000 |
---|---|---|
committer | Thomas Grill <xovo@users.sourceforge.net> | 2003-06-14 02:32:39 +0000 |
commit | f81282808b0d9147fc0c980e418c56774d1f6735 (patch) | |
tree | 40f50ddfb01b1efce4a4a7189722ff85340b5eed /externals/grill/flext/source | |
parent | c0c7359304c7bb54d794c74b260d9b0bd18f02ae (diff) |
""
svn path=/trunk/; revision=702
Diffstat (limited to 'externals/grill/flext/source')
-rw-r--r-- | externals/grill/flext/source/flclass.h | 31 | ||||
-rw-r--r-- | externals/grill/flext/source/flext.cpp | 19 | ||||
-rwxr-xr-x | externals/grill/flext/source/flprefix.h | 17 | ||||
-rwxr-xr-x | externals/grill/flext/source/flqueue.cpp | 178 | ||||
-rw-r--r-- | externals/grill/flext/source/flthr.cpp | 3 |
5 files changed, 162 insertions, 86 deletions
diff --git a/externals/grill/flext/source/flclass.h b/externals/grill/flext/source/flclass.h index 3add0f13..c5559153 100644 --- a/externals/grill/flext/source/flclass.h +++ b/externals/grill/flext/source/flclass.h @@ -730,17 +730,34 @@ private: // queue stuff - class qmsg; - qmsg *qhead,*qtail; +// class qmsg; +// static qmsg *qhead,*qtail; + + //! Flush messages in the queue + static void QFlush(flext_base *th = NULL); + + //! Queue worker function +// static void QWork(bool qlock,bool syslock); + + //! Start message queue + static void StartQueue(); #if FLEXT_SYS == FLEXT_SYS_JMAX - static void QTick(fts_object_t *c, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at); +// static void QTick(int winlet = 0, fts_symbol_t s = NULL, int ac = 0, const fts_atom_t *at = NULL); +#else // PD or Max +// static void QTick(); +#ifndef FLEXT_QTHR +// static t_qelem *qclk; #else - t_qelem *qclk; - static void QTick(flext_base *th); + //! Queue worker thread function +// static void *QWorker(void *); + //! Queue worker thread conditional +// static ThrCond qthrcond; #endif - void Queue(qmsg *m); +#endif + +// static void Queue(qmsg *m); #ifdef FLEXT_THREADS - ThrMutex qmutex; +// static ThrMutex qmutex; #endif diff --git a/externals/grill/flext/source/flext.cpp b/externals/grill/flext/source/flext.cpp index 2eacb118..fc033b21 100644 --- a/externals/grill/flext/source/flext.cpp +++ b/externals/grill/flext/source/flext.cpp @@ -47,12 +47,6 @@ flext_base::flext_base(): } else attrhead = clattrhead = NULL; - - // message queue ticker - qhead = qtail = NULL; -#if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX - qclk = (t_qelem *)(qelem_new(this,(t_method)QTick)); -#endif } flext_base::~flext_base() @@ -67,15 +61,8 @@ flext_base::~flext_base() StopThreads(); #endif - // send remaining pending messages and destroy queue ticker -#if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX - while(qhead) QTick(this); - qelem_free((t_qelem *)qclk); -#elif FLEXT_SYS == FLEXT_SYS_JMAX - while(qhead) QTick((fts_object_t *)thisHdr(),0,NULL,0,NULL); - // this is dangerous because there may be other timers on this object! - fts_timebase_remove_object(fts_get_timebase(), (fts_object_t *)thisHdr()); -#endif + // send remaining pending messages for this object + QFlush(this); // delete message lists if(methhead) delete methhead; @@ -171,6 +158,8 @@ void flext_base::Setup(t_classid id) AddMethod(id,0,"getattributes",(methfun)cb_ListAttrib); SetProxies(c); + + StartQueue(); } #if FLEXT_SYS == FLEXT_SYS_JMAX diff --git a/externals/grill/flext/source/flprefix.h b/externals/grill/flext/source/flprefix.h index dae6822c..87f976a7 100755 --- a/externals/grill/flext/source/flprefix.h +++ b/externals/grill/flext/source/flprefix.h @@ -297,7 +297,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. // #pragma message("Compiling for PD") #endif -// set threading model +// ----- set threading model ----- #ifdef FLEXT_THREADS #undef FLEXT_THREADS #if FLEXT_OS == FLEXT_OS_MAC && FLEXT_SYS == FLEXT_SYS_MAX @@ -308,4 +308,19 @@ WARRANTIES, see the file, "license.txt," in this distribution. #endif #endif +// ----- set message queue mode ----- +#undef FLEXT_QTHR + +#ifdef FLEXT_PDLOCK + // new PD thread locking functionality shall be used + #if FLEXT_SYS == FLEXT_SYS_PD + #ifdef FLEXT_THREADS + // can only be used with PD and threaded build + #define FLEXT_QTHR + #endif + #else + #error FLEXT_PDLOCK can only be defined with PD + #endif #endif + +#endif // __FLEXT_PREFIX_H diff --git a/externals/grill/flext/source/flqueue.cpp b/externals/grill/flext/source/flqueue.cpp index 9d0b27c6..4c819ae7 100755 --- a/externals/grill/flext/source/flqueue.cpp +++ b/externals/grill/flext/source/flqueue.cpp @@ -19,10 +19,10 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include "flext.h" #include "flinternal.h" -class flext_base::qmsg +class qmsg { public: - qmsg(): nxt(NULL),tp(tp_none) {} + qmsg(flext_base *b): th(b),nxt(NULL),tp(tp_none) {} ~qmsg(); qmsg *nxt; @@ -33,9 +33,10 @@ public: void SetFloat(int o,float f) { Clear(); out = o; tp = tp_float; _float = f; } void SetInt(int o,int i) { Clear(); out = o; tp = tp_int; _int = i; } void SetSymbol(int o,const t_symbol *s) { Clear(); out = o; tp = tp_sym; _sym = s; } - void SetList(int o,int argc,const t_atom *argv) { Clear(); out = o; tp = tp_list; _list.argc = argc,_list.argv = CopyList(argc,argv); } - void SetAny(int o,const t_symbol *s,int argc,const t_atom *argv) { Clear(); out = o; tp = tp_any; _any.s = s,_any.argc = argc,_any.argv = CopyList(argc,argv); } + void SetList(int o,int argc,const t_atom *argv) { Clear(); out = o; tp = tp_list; _list.argc = argc,_list.argv = flext::CopyList(argc,argv); } + void SetAny(int o,const t_symbol *s,int argc,const t_atom *argv) { Clear(); out = o; tp = tp_any; _any.s = s,_any.argc = argc,_any.argv = flext::CopyList(argc,argv); } + flext_base *th; int out; enum { tp_none,tp_bang,tp_float,tp_int,tp_sym,tp_list,tp_any } tp; union { @@ -47,43 +48,42 @@ public: }; }; -flext_base::qmsg::~qmsg() +qmsg::~qmsg() { Clear(); if(nxt) delete nxt; } -void flext_base::qmsg::Clear() +void qmsg::Clear() { if(tp == tp_list) { if(_list.argv) delete[] _list.argv; } else if(tp == tp_any) { if(_any.argv) delete[] _any.argv; } tp = tp_none; } -#if FLEXT_SYS == FLEXT_SYS_JMAX -void flext_base::QTick(fts_object_t *c, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) -{ - flext_base *th = thisObject(c); +static qmsg *qhead = NULL,*qtail = NULL; + +#ifdef FLEXT_QTHR +static flext::ThrCond qthrcond; #else -void flext_base::QTick(flext_base *th) -{ +static t_qelem *qclk = NULL; #endif -// post("qtick"); -#if defined(FLEXT_THREADS) && defined(FLEXT_DEBUG) && !defined(FLEXT_PDLOCK) - if(!th->IsSystemThread()) { - error("flext - Queue tick called by wrong thread!"); - return; - } + +#ifdef FLEXT_THREADS +static flext::ThrMutex qmutex; #endif +static void QWork(bool qlock,bool syslock) +{ #ifdef FLEXT_THREADS - th->qmutex.Lock(); + if(qlock) qmutex.Lock(); #endif -#ifdef FLEXT_PDLOCK - pd_lock(); +#ifdef FLEXT_QTHR + if(syslock) pd_lock(); #endif + for(;;) { - qmsg *m = th->qhead; + qmsg *m = qhead; if(!m) break; if(m->out < 0) { @@ -94,30 +94,30 @@ void flext_base::QTick(flext_base *th) switch(m->tp) { case qmsg::tp_bang: - th->m_methodmain(n,sym_bang,0,&tmp); + m->th->m_methodmain(n,flext::sym_bang,0,&tmp); break; case qmsg::tp_float: - SetFloat(tmp,m->_float); - th->m_methodmain(n,sym_float,1,&tmp); + flext::SetFloat(tmp,m->_float); + m->th->m_methodmain(n,flext::sym_float,1,&tmp); break; case qmsg::tp_int: - SetInt(tmp,m->_int); + flext::SetInt(tmp,m->_int); #if FLEXT_SYS == FLEXT_SYS_PD - th->m_methodmain(n,sym_float,1,&tmp); + m->th->m_methodmain(n,flext::sym_float,1,&tmp); #elif FLEXT_SYS == FLEXT_SYS_MAX - th->m_methodmain(n,sym_int,1,&tmp); + m->th->m_methodmain(n,flext::sym_int,1,&tmp); #else #error Not implemented! #endif case qmsg::tp_sym: - SetSymbol(tmp,m->_sym); - th->m_methodmain(n,sym_symbol,1,&tmp); + flext::SetSymbol(tmp,m->_sym); + m->th->m_methodmain(n,flext::sym_symbol,1,&tmp); break; case qmsg::tp_list: - th->m_methodmain(n,sym_list,m->_list.argc,m->_list.argv); + m->th->m_methodmain(n,flext::sym_list,m->_list.argc,m->_list.argv); break; case qmsg::tp_any: - th->m_methodmain(n,m->_any.s,m->_any.argc,m->_any.argv); + m->th->m_methodmain(n,m->_any.s,m->_any.argc,m->_any.argv); break; #ifdef FLEXT_DEBUG default: ERRINTERNAL(); @@ -128,32 +128,64 @@ void flext_base::QTick(flext_base *th) // message to outlet switch(m->tp) { - case qmsg::tp_bang: th->ToOutBang(m->out); break; - case qmsg::tp_float: th->ToOutFloat(m->out,m->_float); break; - case qmsg::tp_int: th->ToOutInt(m->out,m->_int); break; - case qmsg::tp_sym: th->ToOutSymbol(m->out,m->_sym); break; - case qmsg::tp_list: th->ToOutList(m->out,m->_list.argc,m->_list.argv); break; - case qmsg::tp_any: th->ToOutAnything(m->out,m->_any.s,m->_any.argc,m->_any.argv); break; + case qmsg::tp_bang: m->th->ToOutBang(m->out); break; + case qmsg::tp_float: m->th->ToOutFloat(m->out,m->_float); break; + case qmsg::tp_int: m->th->ToOutInt(m->out,m->_int); break; + case qmsg::tp_sym: m->th->ToOutSymbol(m->out,m->_sym); break; + case qmsg::tp_list: m->th->ToOutList(m->out,m->_list.argc,m->_list.argv); break; + case qmsg::tp_any: m->th->ToOutAnything(m->out,m->_any.s,m->_any.argc,m->_any.argv); break; #ifdef FLEXT_DEBUG default: ERRINTERNAL(); #endif } } - th->qhead = m->nxt; - if(!th->qhead) th->qtail = NULL; + qhead = m->nxt; + if(!qhead) qtail = NULL; m->nxt = NULL; delete m; } -#ifdef FLEXT_PDLOCK - pd_unlock(); +#ifdef FLEXT_QTHR + if(syslock) pd_unlock(); +#endif +#ifdef FLEXT_THREADS + if(qlock) qmutex.Unlock(); +#endif +} + +#if FLEXT_SYS == FLEXT_SYS_JMAX +static void QTick(fts_object_t *c,int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) +{ +#else +static void QTick(flext_base *c) +{ +#endif +// post("qtick"); +#if defined(FLEXT_THREADS) && defined(FLEXT_DEBUG) && !defined(FLEXT_QTHR) + if(!flext::IsSystemThread()) { + error("flext - Queue tick called by wrong thread!"); + return; + } #endif + QWork(true,true); +} + +/* +It would be sufficient to only flush messages belonging to object th +But then the order of sent messages is not as intended +*/ +void flext_base::QFlush(flext_base *th) +{ #ifdef FLEXT_THREADS - th->qmutex.Unlock(); + if(!IsSystemThread()) { + error("flext - Queue flush called by wrong thread!"); + return; + } #endif + while(qhead) QWork(true,false); } -void flext_base::Queue(qmsg *m) +static void Queue(qmsg *m) { // post("Queue"); @@ -168,11 +200,11 @@ void flext_base::Queue(qmsg *m) #endif #if FLEXT_SYS == FLEXT_SYS_PD - #ifdef FLEXT_PDLOCK + #ifdef FLEXT_QTHR // wake up a worker thread // (instead of triggering the clock) - clock_delay(qclk,0); - #else + qthrcond.Signal(); + #else clock_delay(qclk,0); #endif #elif FLEXT_SYS == FLEXT_SYS_MAX @@ -181,50 +213,76 @@ void flext_base::Queue(qmsg *m) // this is dangerous because there may be other timers on this object! fts_timebase_add_call(fts_get_timebase(), (fts_object_t *)thisHdr(), QTick, NULL, 0); #else -#error +#error Not implemented +#endif +} + +#ifdef FLEXT_QTHR +void QWorker(flext::thr_params *) +{ + for(;;) { + qthrcond.Wait(); + QWork(true,true); + } +} +#endif + +void flext_base::StartQueue() +{ + // message queue ticker + qhead = qtail = NULL; + +#ifdef FLEXT_QTHR + LaunchThread(QWorker,NULL); +#else +#if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX + qclk = (t_qelem *)(qelem_new(NULL,(t_method)QTick)); +#else +#error Not implemented! +#endif #endif } void flext_base::ToQueueBang(int o) const { - qmsg *m = new qmsg(); + qmsg *m = new qmsg(const_cast<flext_base *>(this)); m->SetBang(o); - const_cast<flext_base &>(*this).Queue(m); + Queue(m); } void flext_base::ToQueueFloat(int o,float f) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast<flext_base *>(this)); m->SetFloat(o,f); - const_cast<flext_base &>(*this).Queue(m); + Queue(m); } void flext_base::ToQueueInt(int o,int f) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast<flext_base *>(this)); m->SetInt(o,f); - const_cast<flext_base &>(*this).Queue(m); + Queue(m); } void flext_base::ToQueueSymbol(int o,const t_symbol *s) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast<flext_base *>(this)); m->SetSymbol(o,s); - const_cast<flext_base &>(*this).Queue(m); + Queue(m); } void flext_base::ToQueueList(int o,int argc,const t_atom *argv) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast<flext_base *>(this)); m->SetList(o,argc,argv); - const_cast<flext_base &>(*this).Queue(m); + Queue(m); } void flext_base::ToQueueAnything(int o,const t_symbol *s,int argc,const t_atom *argv) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast<flext_base *>(this)); m->SetAny(o,s,argc,argv); - const_cast<flext_base &>(*this).Queue(m); + Queue(m); } diff --git a/externals/grill/flext/source/flthr.cpp b/externals/grill/flext/source/flthr.cpp index 5c4a31c8..3bd5bbf4 100644 --- a/externals/grill/flext/source/flthr.cpp +++ b/externals/grill/flext/source/flthr.cpp @@ -283,8 +283,6 @@ bool flext_base::StopThreads() #endif // --- all object threads have terminated by now ------- - - qmutex.Lock(); // Lock message queue tlmutex.Lock(); // timeout -> hard termination @@ -306,7 +304,6 @@ bool flext_base::StopThreads() thrhead = NULL; tlmutex.Unlock(); - qmutex.Unlock(); } // post("All threads have terminated"); |