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

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