aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/flext/source/flthr.cpp
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2002-12-15 04:35:27 +0000
committerThomas Grill <xovo@users.sourceforge.net>2002-12-15 04:35:27 +0000
commita0cb0bd2e02740e50ec16dde2fb4e07f1702d1d0 (patch)
tree8647f172ee53287e3c9e24c127628a97deb0f761 /externals/grill/flext/source/flthr.cpp
parent5bfb9859c430f83c39628217e19883bed23158ea (diff)
""
svn path=/trunk/; revision=302
Diffstat (limited to 'externals/grill/flext/source/flthr.cpp')
-rw-r--r--externals/grill/flext/source/flthr.cpp164
1 files changed, 160 insertions, 4 deletions
diff --git a/externals/grill/flext/source/flthr.cpp b/externals/grill/flext/source/flthr.cpp
index f23eb38f..97da5584 100644
--- a/externals/grill/flext/source/flthr.cpp
+++ b/externals/grill/flext/source/flthr.cpp
@@ -23,16 +23,146 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include <errno.h>
+//! Thread id of system thread
+pthread_t flext_base::thrid;
+
+//! Thread id of helper thread
+pthread_t flext_base::thrhelpid;
+
+flext_base::thr_entry *flext_base::thrhead = NULL,*flext_base::thrtail = NULL;
+flext::ThrMutex flext_base::tlmutex;
+
+//! Helper thread should terminate
+bool thrhelpexit = false;
+
+flext::ThrCond *thrhelpcond = NULL;
+
+//! Start helper thread
+bool flext_base::StartHelper()
+{
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
+
+ thrhelpexit = false;
+ int ret = pthread_create (&thrhelpid,&attr,(void *(*)(void *))ThrHelper,NULL);
+ if(ret) {
+ error((char *)("flext - Could not launch helper thread!"));
+ return false;
+ }
+ else
+ return true;
+}
+
+#if 0
+/*! \brief Stop helper thread
+ \note not called!
+*/
+bool flext_base::StopHelper()
+{
+ thrhelpexit = true;
+ if(thrhelpcond) thrhelpcond->Signal();
+}
+#endif
+
+//! Static helper thread function
+void flext_base::ThrHelper(void *)
+{
+ // set prototype thread attributes
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
+
+ // set thread priority one point below normal
+ // so thread construction won't disturb real-time audio
+ sched_param parm;
+ int policy;
+ pthread_getschedparam(thrhelpid,&policy,&parm);
+ int prio = parm.sched_priority;
+ int schmin = sched_get_priority_min(policy);
+ if(prio > schmin) {
+ parm.sched_priority = prio-1;
+ pthread_setschedparam(thrhelpid,policy,&parm);
+ }
+
+ thrhelpcond = new ThrCond;
+
+ // helper loop
+ for(;;) {
+ thrhelpcond->Wait();
+ if(thrhelpexit) break;
+
+ tlmutex.Lock();
+
+ // start all inactive threads in queue
+ thr_entry *prv = NULL,*ti;
+ for(ti = thrhead; ti; prv = ti,ti = ti->nxt) {
+ if(!ti->active) {
+ int ret = pthread_create (&ti->thrid,&attr,(void *(*)(void *))ti->meth,ti->params);
+ if(ret) {
+ error((char *)("flext - Could not launch thread!"));
+
+ // delete from queue
+ if(prv)
+ prv->nxt = ti->nxt;
+ else
+ thrhead = ti->nxt;
+ if(thrtail == ti) thrtail = prv;
+
+ ti->nxt = NULL;
+ delete ti;
+ }
+ else {
+ // set active flag
+ ti->active = true;
+ }
+ }
+ }
+
+ tlmutex.Unlock();
+ }
+
+ delete thrhelpcond;
+ thrhelpcond = NULL;
+}
+
+
+bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *methname)
+{
+#ifdef FLEXT_DEBUG
+ if(!p || !thrhelpcond) {
+ ERRINTERNAL();
+ return false;
+ }
+#endif
+
+ tlmutex.Lock();
+
+ // make an entry into thread list
+ thr_entry *nt = new thr_entry(this,meth,p);
+ if(thrtail) thrtail->nxt = nt;
+ else thrhead = nt;
+ thrtail = nt;
+
+ // signal thread helper
+ thrhelpcond->Signal();
+
+ tlmutex.Unlock();
+ return true;
+}
+
+/*
bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *methname)
{
- static bool init = false;
- static pthread_attr_t attr;
#ifdef FLEXT_DEBUG
if(!p) {
ERRINTERNAL();
return false;
}
#endif
+
+ static bool init = false;
+ static pthread_attr_t attr;
if(!init) {
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
@@ -62,8 +192,9 @@ bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *me
if(ret) {
#ifdef FLEXT_DEBUG
error((char *)(ret == EAGAIN?"%s - Unsufficient resources to launch thread!":"%s - Could not launch method!"),methname);
-#endif
+#else
error((char *)("%s - Could not launch method!"),methname);
+#endif
delete p;
return false;
@@ -71,6 +202,7 @@ bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *me
else
return true;
}
+*/
bool flext_base::PushThread()
{
@@ -78,12 +210,13 @@ bool flext_base::PushThread()
// post("Push thread");
+/*
// make an entry into thread list
thr_entry *nt = new thr_entry;
if(thrtail) thrtail->nxt = nt;
else thrhead = nt;
thrtail = nt;
-
+*/
{
#if FLEXT_OS == FLEXT_OS_WIN
// set detached thread to lower priority class
@@ -151,6 +284,29 @@ void flext_base::PopThread()
tlmutex.Unlock();
}
+void flext_base::TermThreads()
+{
+ // wait for thread termination
+ shouldexit = true;
+ for(int wi = 0; thrhead && wi < 100; ++wi) Sleep(0.01f);
+
+ qmutex.Lock(); // Lock message queue
+ tlmutex.Lock();
+
+ // timeout -> hard termination
+ for(thr_entry *t = thrhead; t; )
+ if(t->th == this) {
+ if(pthread_cancel(t->thrid)) post("%s - Thread could not be terminated!",thisName());
+ thr_entry *tn = t->nxt;
+ t->nxt = NULL; delete t;
+ t = tn;
+ }
+ else t = t->nxt;
+
+ tlmutex.Unlock();
+ qmutex.Unlock();
+}
+
flext_base::thrid_t flext_base::GetThreadId()
{
return pthread_self();