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,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 <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)) // 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
}
|