source: trunk/MagicSoft/Cosy/base/msgqueue.cc@ 1954

Last change on this file since 1954 was 1953, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 6.0 KB
Line 
1#include "msgqueue.h"
2
3#include <iostream.h>
4
5#include <unistd.h> // usleep
6#include <sys/resource.h> // PRIO_PROCESS
7
8#undef DEBUG
9
10// --------------------------------------------------------------------------
11//
12// This creates the Message queue thread,
13//
14MsgQueue::MsgQueue() : fBreak(0)
15{
16 fMp = new unsigned char;
17 pthread_create(&fThread, NULL, MapThread, this);
18}
19
20// --------------------------------------------------------------------------
21//
22// The destructor terminates the thread.
23//
24MsgQueue::~MsgQueue()
25{
26#ifdef DEBUG
27 cout << "~MsgQueue::MsgQueue" << endl;
28#endif
29 pthread_cancel(fThread);
30 delete (unsigned char*)fMp;
31}
32
33// --------------------------------------------------------------------------
34//
35// This is the function which must be overloaded.
36// Here you process the messages. mp is a pointer which you can
37// specify when posting the message.
38//
39// If a new messages is posted while the old one is not yet
40// finished the fBreak flag is set. Please test this flag with
41// Break() and try to finish (or stop) the current action as soon
42// as possible. This makes sure, that before a new action is started
43// the old action can be finished correctly by the user.
44//
45void *MsgQueue::Proc(int msg, void *mp)
46{
47 return NULL;
48}
49
50// --------------------------------------------------------------------------
51//
52// This is the thread mapper.
53//
54void *MsgQueue::MapThread(void *arg)
55{
56 pthread_detach(pthread_self());
57
58 setpriority(PRIO_PROCESS, 0, -5);
59
60 ((MsgQueue*)arg)->Thread();
61
62 return NULL;
63}
64
65// --------------------------------------------------------------------------
66//
67// This is the thread which handles the processing.
68// As soon as a message is posted the fBreak flag is set (see PostMsg)
69// And as soon as the current action is finished the new action is executed
70// in this thread. This makes sure, that the calling program is not stalled.
71//
72void MsgQueue::Thread()
73{
74 //
75 // Tell the poster that processing is done
76 //
77 fStart = 0;
78 while (!fBreak)
79 usleep(1);
80
81 while(1)
82 {
83 while (!fStart)
84 usleep(1);
85 fStart = 0;
86
87 //
88 // This makes sure that also a very fast Break() after
89 // a PostMsg is processed correctly
90 //
91 pthread_mutex_lock(&fMuxMsg);
92 fBreak = 0;
93 pthread_mutex_unlock(&fMuxMsg);
94
95#ifdef DEBUG
96 cout << "MsgQueue::Thread: Processing Msg 0x" << hex << fMsg << endl;
97#endif
98 // --- bool quit = fMsg==WM_QUIT;
99 fRc=Proc(fMsg, fMp);
100#ifdef DEBUG
101 cout << "MsgQueue::PostMsg: Msg 0x" << hex << fMsg << " processed (rc=" << fRc << ")" << endl;
102#endif
103
104 // --- if (quit)
105 // --- break;
106 }
107
108 // --- fStart = 0;
109 // --- cout << "WM_QUIT posted... leaving msg queue." << endl;
110}
111
112// --------------------------------------------------------------------------
113//
114// Use this function to post a message.
115// mp can be a pointer to a data structure. size should be the size of it.
116// size bytes of this structure are copied and a pointer to the copy
117// is forwarded to the Proc function.
118//
119void *MsgQueue::PostMsg(int msg, void *mp, int size)
120{
121 //
122 // Lock Mutex, put msg on stack and tell thread to process message
123 //
124
125 //
126 // Make sure that only one Proc() is running and can be stopped
127 // stopped and the messages are processed serialized
128 //
129#ifdef DEBUG
130 cout << "MsgQueue::PostMsg: Locking MsgQueue mutex..." << flush;
131#endif
132 pthread_mutex_lock(&fMuxMsg);
133#ifdef DEBUG
134 cout << "done." << endl;
135#endif
136
137 //
138 // Set break state and wait until Proc() returned (break state deleted)
139 // This means, that a new command is invoked and (if forseen) the
140 // running command should stop execution.
141 //
142 // This is some kind of controlled user break without using signals
143 //
144 /**** NEW 20/01/2003 ****/
145 if (fBreak)
146 {
147 pthread_mutex_unlock(&fMuxMsg);
148#ifdef DEBUG
149 cout << "------------> MsgQueue::PostMsg: Proc still pending... Message IGNORED." << endl;
150#endif
151 return NULL;
152 }
153 /**** NEW 20/01/2003 ****/
154#ifdef DEBUG
155 cout << "MsgQueue::PostMsg: ---> Break <---" << endl;
156#endif
157 fBreak = 1;
158
159 //
160 // copy return code from Proc() and set new message
161 //
162 void *rc = fRc;
163
164 fMsg = msg;
165
166 delete (unsigned char*)fMp;
167 fMp = new unsigned char[size];
168
169 memcpy(fMp, mp, size);
170
171 //
172 // Start Proc()
173 //
174#ifdef DEBUG
175 cout << "MsgQueue::PostMsg: Releasing MsgQueue mutex..." << flush;
176#endif
177 fStart = 1;
178 pthread_mutex_unlock(&fMuxMsg);
179#ifdef DEBUG
180 cout << "done." << endl;
181#endif
182
183 /*
184 * **** NEW 20/01/2003 ***
185 *
186 * This can halt the main thread, because it is waiting until
187 * Proc has finished its execution which can take a while
188 *
189 * A side effect is, because you don't wait for the end of
190 * the execution of Proc, if a new message is posted fBreak
191 * and fStart is set again, new values are copied to fMsg and
192 * fMp (FIXME? Harmefull?) and the message is not processed at all.
193 */
194 //while (fStart)
195 // usleep(1);
196
197#ifdef DEBUG
198 cout << "MsgQueue::PostMsg: Returning rc = " << hex << rc << endl;
199#endif
200 return rc;
201}
202/*
203Start positioning.
204MsgQueue::PostMsg: Locking MsgQueue mutex...done.
205MsgQueue::PostMsg: ---> Break <---
206+++++ MsgQueue::PostMsg: Releasing MsgQueue mutex...done.
207
208===== MsgQueue::PostMsg: Returning rc = (nil)
209PostMsg (WM_Position) returned.
210done.
211Stopping movement...Movement stopped.
212WM_Position: done. (return 0x7777)
213MsgQueue::PostMsg: Msg 0x1001 processed (rc=0x7777)
214MsgQueue::Thread: Processing Msg 0x1001
215WM_Position: start.
216Positioning to Target...
217 */
218/*
219Start positioning.
220MsgQueue::PostMsg: Locking MsgQueue mutex...done.
221MsgQueue::PostMsg: ---> Break <---
222+++++ MsgQueue::PostMsg: Releasing MsgQueue mutex...done.
223
224done.
225Stopping movement...Movement stopped.
226WM_Position: done. (return 0x7777)
227MsgQueue::PostMsg: Msg 0x1001 processed (rc=0x7777)
228MsgQueue::Thread: Processing Msg 0x1001
229WM_Position: start.
230Positioning to Target...
231===== MsgQueue::PostMsg: Returning rc = (nil)
232*/
Note: See TracBrowser for help on using the repository browser.