aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/flext/source
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
parentc0c7359304c7bb54d794c74b260d9b0bd18f02ae (diff)
""
svn path=/trunk/; revision=702
Diffstat (limited to 'externals/grill/flext/source')
-rw-r--r--externals/grill/flext/source/flclass.h31
-rw-r--r--externals/grill/flext/source/flext.cpp19
-rwxr-xr-xexternals/grill/flext/source/flprefix.h17
-rwxr-xr-xexternals/grill/flext/source/flqueue.cpp178
-rw-r--r--externals/grill/flext/source/flthr.cpp3
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");