/* flext tutorial - threads 2 Copyright (c) 2002,2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This shows an example of multiple threads and syncing with a thread conditional */ /* define FLEXT_THREADS for thread usage. Flext must also have been compiled with that defined! it's even better to define that as a compiler flag (-D FLEXT_THREADS) for all files of the flext external */ #ifndef FLEXT_THREADS #define FLEXT_THREADS #endif #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif class thread2: public flext_base { FLEXT_HEADER(thread2,flext_base) public: thread2(int del); protected: void m_start(int st); void m_stop(); void m_text(); void m_textout(); private: FLEXT_THREAD_I(m_start) // define threaded callback for method m_start FLEXT_CALLBACK(m_stop) // normal callback for m_stop FLEXT_CALLBACK(m_text) // turn on console output FLEXT_THREAD(m_textout) // text output float delay; volatile int count; // caution: CodeWarrior seems to ignore volatile modifier!! volatile bool stopit,running,blipping; // flags for running and stopping // thread conditional for stop signal ThrCond cond; }; FLEXT_NEW_1("thread2",thread2,int) thread2::thread2(int del): delay(del/1000.f), stopit(false), running(false),blipping(false) { AddInAnything(); AddOutInt(2); FLEXT_ADDMETHOD(0,m_start); // register start for integer numbers (floats in PD) FLEXT_ADDMETHOD_(0,"text",m_text); // register m_text method for "text" tag FLEXT_ADDMETHOD_(0,"stop",m_stop); // register m_text method for "stop" tag } void thread2::m_start(int st) { // if already running, just set back the counter if(running) { count = st; return; } running = true; // loop until either the system exit flag or the "stopit" flag is set for(count = st; !ShouldExit() && !stopit; ++count) { Sleep(delay); ToOutInt(0,count); // output loop count } running = false; // change state flag // cond.Lock(); // lock conditional cond.Signal(); // signal changed flag to waiting "stop" method // cond.Unlock(); // unlock conditional } void thread2::m_stop() { // cond.Lock(); // lock conditional stopit = true; // set termination flag while(*(&running) || *(&blipping)) // workaround for CodeWarrior (doesn't honor volatile modifier!) { cond.Wait(); // wait for signal by running threads } // --- Here, the threads should have stopped --- stopit = false; // reset flag // cond.Unlock(); // unlock conditional } void thread2::m_text() { FLEXT_CALLMETHOD(m_textout); } void thread2::m_textout() { if(blipping) return; blipping = true; while(!ShouldExit() && !stopit) { post("%i",count); Sleep(1.f); } blipping = false; // change state flag // cond.Lock(); // lock conditional cond.Signal(); // signal changed flag to waiting "stop" method // cond.Unlock(); // unlock conditional }