aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/flext/source/flqueue.cpp
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2003-06-14 02:32:39 +0000
committerThomas Grill <xovo@users.sourceforge.net>2003-06-14 02:32:39 +0000
commitf81282808b0d9147fc0c980e418c56774d1f6735 (patch)
tree40f50ddfb01b1efce4a4a7189722ff85340b5eed /externals/grill/flext/source/flqueue.cpp
parentc0c7359304c7bb54d794c74b260d9b0bd18f02ae (diff)
""
svn path=/trunk/; revision=702
Diffstat (limited to 'externals/grill/flext/source/flqueue.cpp')
-rwxr-xr-xexternals/grill/flext/source/flqueue.cpp178
1 files changed, 118 insertions, 60 deletions
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);
}