1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/*
flext tutorial - threads 2
Copyright (c) 2002-2022 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 <flext.h>
#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)
{
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
}
|