diff options
author | Thomas Grill <xovo@users.sourceforge.net> | 2003-06-30 02:33:10 +0000 |
---|---|---|
committer | Thomas Grill <xovo@users.sourceforge.net> | 2003-06-30 02:33:10 +0000 |
commit | 86bdc7d828f8df51a072da396217ce6c38b7034a (patch) | |
tree | 4c5bbfeadd75ba0821c54d02f6103e74811e7b3a | |
parent | d5c52075e76d9eb3a373b6367f59d457ee9e7c71 (diff) |
""
svn path=/trunk/; revision=739
-rw-r--r-- | externals/grill/flext/changes.txt | 2 | ||||
-rw-r--r-- | externals/grill/flext/flext.vcproj | 3 | ||||
-rw-r--r-- | externals/grill/flext/flext_sh.dsp | 2 | ||||
-rw-r--r-- | externals/grill/flext/source/flsupport.cpp | 35 | ||||
-rw-r--r-- | externals/grill/flext/source/flsupport.h | 47 | ||||
-rw-r--r-- | externals/grill/flext/source/flthr.cpp | 47 | ||||
-rw-r--r-- | externals/grill/flext/tutorial/adv3/main.cpp | 3 | ||||
-rw-r--r-- | externals/grill/flext/tutorial/pd/ex-signal1.pd | 30 | ||||
-rw-r--r-- | externals/grill/flext/tutorial/stk2/main.cpp | 2 |
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;"f:\prog\pd\pd-cvs\bin";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; |