aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2003-06-30 02:33:10 +0000
committerThomas Grill <xovo@users.sourceforge.net>2003-06-30 02:33:10 +0000
commit86bdc7d828f8df51a072da396217ce6c38b7034a (patch)
tree4c5bbfeadd75ba0821c54d02f6103e74811e7b3a
parentd5c52075e76d9eb3a373b6367f59d457ee9e7c71 (diff)
""
svn path=/trunk/; revision=739
-rw-r--r--externals/grill/flext/changes.txt2
-rw-r--r--externals/grill/flext/flext.vcproj3
-rw-r--r--externals/grill/flext/flext_sh.dsp2
-rw-r--r--externals/grill/flext/source/flsupport.cpp35
-rw-r--r--externals/grill/flext/source/flsupport.h47
-rw-r--r--externals/grill/flext/source/flthr.cpp47
-rw-r--r--externals/grill/flext/tutorial/adv3/main.cpp3
-rw-r--r--externals/grill/flext/tutorial/pd/ex-signal1.pd30
-rw-r--r--externals/grill/flext/tutorial/stk2/main.cpp2
9 files changed, 135 insertions, 36 deletions
diff --git a/externals/grill/flext/changes.txt b/externals/grill/flext/changes.txt
index 312dab3a..4fcc9bf2 100644
--- a/externals/grill/flext/changes.txt
+++ b/externals/grill/flext/changes.txt
@@ -21,6 +21,8 @@ Version history:
- added flext_base::DumpAttrib to send an attribute value to the attribute outlet
- added "getmethods" message (for attribute-enabled externals) to list methods for a specified inlet (default = 0)
- "getattributes" or "getmethods" output lists are now alphabethically sorted
+- flext::StopThread function to terminate running threads (started with LaunchThread)
+- added flext::post() and flext::error() console printing (thread-safe)
0.4.4:
- fixed deadly bug for Max/MSP method-to-symbol-binding proxies
diff --git a/externals/grill/flext/flext.vcproj b/externals/grill/flext/flext.vcproj
index 6f5da0be..33ac33d0 100644
--- a/externals/grill/flext/flext.vcproj
+++ b/externals/grill/flext/flext.vcproj
@@ -362,7 +362,7 @@
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
- DebugInformationFormat="4"
+ DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
@@ -371,6 +371,7 @@
AdditionalDependencies="pd.lib pthreadVC.lib stk_d.lib sndobj.lib"
OutputFile=".\pd-msvc\flext_ld.dll"
AdditionalLibraryDirectories="f:\prog\packs\pthreads;&quot;f:\prog\pd\pd-cvs\bin&quot;;F:\prog\audio\stk\lib;F:\prog\audio\sndobj\lib"
+ GenerateDebugInformation="TRUE"
OptimizeReferences="1"
ImportLibrary="./pd-msvc/flext_ld.lib"/>
<Tool
diff --git a/externals/grill/flext/flext_sh.dsp b/externals/grill/flext/flext_sh.dsp
index 5f6e4c4b..73767012 100644
--- a/externals/grill/flext/flext_sh.dsp
+++ b/externals/grill/flext/flext_sh.dsp
@@ -109,7 +109,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib sndobj.lib stk_d.lib /nologo /dll /debug /machine:I386 /out:"../flext/pd-msvc/flext_d.dll" /pdbtype:sept /libpath:"f:\prog\audio\sndobj\lib" /libpath:"f:\prog\audio\stk\lib"
-# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib sndobj.lib stk_d.lib /nologo /dll /debug /machine:I386 /out:"pd-msvc/flext_dl.dll" /pdbtype:sept /libpath:"f:\prog\audio\sndobj\lib" /libpath:"f:\prog\audio\stk\lib"
+# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib sndobj.lib stk_d.lib /nologo /dll /debug /machine:I386 /out:"pd-msvc/flext_ld.dll" /pdbtype:sept /libpath:"f:\prog\audio\sndobj\lib" /libpath:"f:\prog\audio\stk\lib"
!ELSEIF "$(CFG)" == "flext_sh - Win32 DLL Release"
diff --git a/externals/grill/flext/source/flsupport.cpp b/externals/grill/flext/source/flsupport.cpp
index ac501f78..9e6a2491 100644
--- a/externals/grill/flext/source/flsupport.cpp
+++ b/externals/grill/flext/source/flsupport.cpp
@@ -14,6 +14,9 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include "flext.h"
+#include <stdio.h>
+#include <stdarg.h>
+
const t_symbol *flext::sym_float = NULL;
const t_symbol *flext::sym_symbol = NULL;
const t_symbol *flext::sym_bang = NULL;
@@ -171,3 +174,35 @@ int flext::Int2Bits(unsigned long n)
return b;
}
+void flext::post(const char *fmt, ...)
+{
+#ifdef FLEXT_THREADS
+ static ThrMutex mutex;
+ mutex.Lock();
+#endif
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ putc('\n', stderr);
+#ifdef FLEXT_THREADS
+ mutex.Unlock();
+#endif
+}
+
+void flext::error(const char *fmt,...)
+{
+#ifdef FLEXT_THREADS
+ static ThrMutex mutex;
+ mutex.Lock();
+#endif
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "error: ");
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ putc('\n', stderr);
+#ifdef FLEXT_THREADS
+ mutex.Unlock();
+#endif
+}
diff --git a/externals/grill/flext/source/flsupport.h b/externals/grill/flext/source/flsupport.h
index 6762c9c2..72bfcf3e 100644
--- a/externals/grill/flext/source/flsupport.h
+++ b/externals/grill/flext/source/flsupport.h
@@ -18,6 +18,10 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include "flstdc.h"
#include <time.h>
+#if FLEXT_OS == FLEXT_OS_WIN
+#include <sys/timeb.h>
+#endif
+
class FLEXT_SHARE flext_base;
/*! \brief Flext support class
@@ -53,12 +57,10 @@ public:
// --- console output -----------------------------------------------
-#if FLEXT_SYS == FLEXT_SYS_JMAX
//! post message to console
static void post(const char *s,...);
//! post error message to console
static void error(const char *s,...);
-#endif
// --- memory -------------------------------------------------------
@@ -608,7 +610,7 @@ public:
/*! \brief Thread parameters
\internal
*/
- class thr_params
+ class FLEXT_SHARE thr_params
{
public:
thr_params(int n = 1);
@@ -632,7 +634,7 @@ public:
/*! \brief This represents an entry to the list of active method threads
\internal
*/
- class thr_entry
+ class FLEXT_SHARE thr_entry
{
public:
thr_entry(void (*m)(thr_params *),thr_params *p,thrid_t id = GetThreadId());
@@ -780,22 +782,31 @@ public:
/*! \brief Wait for condition (for a certain time).
\param ftime Wait time in seconds
\ret 0 = signalled, 1 = timed out
- \remark Depending on the implementation ftime may not be fractional.
- \remark So if ftime = 0 this may suck away your cpu if used in a signalled loop.
+ \remark If ftime = 0 this may suck away your cpu if used in a signalled loop.
*/
bool TimedWait(double ftime)
{
timespec tm;
-#if 0 // find out when the following is defined
+#if FLEXT_OS == FLEXT_OS_WIN
+ _timeb tmb;
+ _ftime(&tmb);
+ tm.tv_nsec = tmb.millitm*1000000;
+ tm.tv_sec = tmb.time;
+#else
+ #if 0 // find out when the following is defined
clock_gettime(CLOCK_REALTIME,tm);
+ #else
+ struct timeval tp;
+ rs = gettimeofday(&tp, NULL);
+ tm.tv_nsec = tp.tv_usec*1000;
+ tm.tv_sec = tp.tv_sec;
+ #endif
+#endif
tm.tv_nsec += (long)((ftime-(long)ftime)*1.e9);
long nns = tm.tv_nsec%1000000000;
tm.tv_sec += (long)ftime+(tm.tv_nsec-nns)/1000000000;
tm.tv_nsec = nns;
-#else
- tm.tv_sec = time(NULL)+(long)ftime;
- tm.tv_nsec = 0;
-#endif
+
Lock();
bool ret = pthread_cond_timedwait(&cond,&mutex,&tm) == 0;
Unlock();
@@ -854,9 +865,19 @@ public:
static void PopThread();
/*! \brief Launch a thread.
- \remark thr_params *p may be NULL if not needed.
+ \param meth Thread function
+ \param params Parameters to pass to the thread, may be NULL if not needed.
+ \return Thread id on success, NULL on failure
+ */
+ static bool LaunchThread(void (*meth)(thr_params *p),thr_params *params = NULL);
+
+ /*! \brief Terminate a thread.
+ \param meth Thread function
+ \param params Parameters to pass to the thread, may be NULL if not needed.
+ \return True if at least one matching thread has been found.
+ \remark Terminates all running threads with matching meth and params.
*/
- static bool LaunchThread(void (*meth)(thr_params *p),thr_params *p = NULL);
+ static bool StopThread(void (*meth)(thr_params *p),thr_params *params = NULL,bool wait = false);
//! @} FLEXT_S_THREAD
diff --git a/externals/grill/flext/source/flthr.cpp b/externals/grill/flext/source/flthr.cpp
index 3bd5bbf4..84623a3d 100644
--- a/externals/grill/flext/source/flthr.cpp
+++ b/externals/grill/flext/source/flthr.cpp
@@ -25,10 +25,6 @@ flext::thrid_t flext::thrid = 0;
//! Thread id of helper thread
flext::thrid_t flext::thrhelpid = 0;
-/*
-flext::thr_entry *flext::thrhead = NULL,*flext::thrtail = NULL;
-flext::ThrMutex flext::tlmutex;
-*/
static flext::thr_entry *thrhead = NULL,*thrtail = NULL;
static flext::ThrMutex tlmutex;
@@ -198,6 +194,49 @@ bool flext::LaunchThread(void (*meth)(thr_params *p),thr_params *p)
return true;
}
+bool flext::StopThread(void (*meth)(thr_params *p),thr_params *p,bool wait)
+{
+#ifdef FLEXT_DEBUG
+ if(!thrhelpcond) {
+ ERRINTERNAL();
+ return false;
+ }
+#endif
+
+ int found = 0;
+
+ tlmutex.Lock();
+ for(thr_entry *ti = thrhead; ti; ti = ti->nxt)
+ // set shouldexit if meth and params match
+ if(ti->meth == meth && ti->params == p) { ti->shouldexit = true; found++; }
+ tlmutex.Unlock();
+
+ if(found) {
+ // signal thread helper
+ thrhelpcond->Signal();
+
+ int cnt = 0;
+ for(int wi = 0; wi < 100; ++wi) {
+ // lock and count this object's threads
+ cnt = 0;
+ tlmutex.Lock();
+ for(thr_entry *t = thrhead; t; t = t->nxt)
+ if(t->meth == meth && t->params == p) ++cnt;
+ tlmutex.Unlock();
+
+ // if no threads are remaining, we are done
+ if(!cnt) break;
+
+ // Wait
+ Sleep(0.01f);
+ }
+
+ return cnt == 0;
+ }
+ else
+ return false;
+}
+
bool flext_base::ShouldExit() const
{
bool ret = true;
diff --git a/externals/grill/flext/tutorial/adv3/main.cpp b/externals/grill/flext/tutorial/adv3/main.cpp
index 608897e6..ae557e26 100644
--- a/externals/grill/flext/tutorial/adv3/main.cpp
+++ b/externals/grill/flext/tutorial/adv3/main.cpp
@@ -16,7 +16,7 @@ flext doesn't support default arguments, hence a message "bound 1" will translat
This can be easily circumvented by using a method digesting a variable argument list, but
was omitted for the sake of clearness.
-Apart from that you'll notice several differences:
+Apart from that you'll notice several differences to the original C object:
- with flext, callbacks have to be declared for all registered methods
- Flext allows the full usage of integer types
- there are no real "passive" methods with flext.
@@ -24,7 +24,6 @@ Apart from that you'll notice several differences:
- Help symbols can't be defined that freely. This is because in Max/MSP help files always
have the name of the object with a suffix .help appended.
However with flext, a path to the respective help file may be specified
-
*/
// include flext header
diff --git a/externals/grill/flext/tutorial/pd/ex-signal1.pd b/externals/grill/flext/tutorial/pd/ex-signal1.pd
index b1c085d2..f2b127d5 100644
--- a/externals/grill/flext/tutorial/pd/ex-signal1.pd
+++ b/externals/grill/flext/tutorial/pd/ex-signal1.pd
@@ -1,21 +1,23 @@
-#N canvas 335 232 584 289 12;
-#X obj 253 92 hsl 128 15 0 1 0 0 empty empty empty 20 8 0 8 -261681
--1 -1 5800 1;
-#X obj 31 92 osc~ 440;
-#X obj 90 246 dac~;
-#X obj 126 92 osc~ 880;
-#X obj 100 173 signal1~;
+#N canvas 335 232 586 291 12;
+#X obj 250 121 hsl 128 15 0 1 0 0 empty empty empty 20 8 0 8 -261681
+-1 -1 0 1;
+#X obj 28 121 osc~ 440;
+#X obj 87 248 dac~;
+#X obj 123 121 osc~ 880;
+#X obj 97 175 signal1~;
#X obj 16 8 cnv 15 550 40 empty empty signal1 10 22 0 24 -260818 -1
0;
#X text 175 28 http://www.parasitaere-kapazitaeten.net;
-#X text 345 109 control the mixing;
-#X text 169 208 adjust the volume;
-#X obj 100 207 *~ 0.5;
-#X text 28 73 source 1;
-#X text 128 72 source 2;
-#X obj 251 114 nbx 5 16 0 1 0 0 empty empty empty 0 -6 0 12 -261681
--1 -1 0.456693 256;
+#X text 342 138 control the mixing;
+#X text 166 210 adjust the volume;
+#X obj 97 209 *~ 0.5;
+#X text 25 102 source 1;
+#X text 125 101 source 2;
+#X obj 248 143 nbx 5 16 0 1 0 0 empty empty empty 0 -6 0 12 -261681
+-1 -1 0 256;
#X text 175 8 flext tutorial \, (C)2002 \, 2003 Thomas Grill;
+#X text 21 51 this is a port of IOhannes Zmoelnigs pan~ example;
+#X text 21 66 done by Frank Barknecht;
#X connect 0 0 12 0;
#X connect 1 0 4 0;
#X connect 3 0 4 1;
diff --git a/externals/grill/flext/tutorial/stk2/main.cpp b/externals/grill/flext/tutorial/stk2/main.cpp
index bb440c91..b356d020 100644
--- a/externals/grill/flext/tutorial/stk2/main.cpp
+++ b/externals/grill/flext/tutorial/stk2/main.cpp
@@ -86,7 +86,7 @@ bool stk2::NewObjs()
vec = new MY_FLOAT[Blocksize()];
}
catch (StkError &) {
- post("%s - Noise() setup failed!",thisName());
+ post("%s - Creation failed!",thisName());
ok = false;
}
return ok;