source: trunk/Cosy/base/msgqueue.cc

Last change on this file was 16779, checked in by tbretz, 11 years ago
A less CPU hungry version of the msg queue using C++11 techniques.
File size: 2.8 KB
Line 
1#include "msgqueue.h"
2
3#include <iostream>
4
5using namespace std;
6
7// --------------------------------------------------------------------------
8//
9// This creates the Message queue thread,
10//
11MsgQueue::MsgQueue() : fState(kRun), fThread(std::bind(&MsgQueue::Thread, this))
12{
13}
14
15// --------------------------------------------------------------------------
16//
17// The destructor terminates the thread.
18//
19MsgQueue::~MsgQueue()
20{
21 CancelThread();
22}
23
24void MsgQueue::CancelThread()
25{
26 const std::lock_guard<std::mutex> lock(fMutex);
27 if (fState!=kIdle)
28 return;
29
30 fState = kAbort;
31 fCond.notify_one();
32 fThread.join();
33}
34
35// --------------------------------------------------------------------------
36//
37// This is the function which must be overloaded.
38// Here you process the messages. mp is a pointer which you can
39// specify when posting the message.
40//
41// If a new messages is posted while the old one is not yet
42// finished the fBreak flag is set. Please test this flag with
43// Break() and try to finish (or stop) the current action as soon
44// as possible. This makes sure, that before a new action is started
45// the old action can be finished correctly by the user.
46//
47int MsgQueue::Proc(int msg, void *mp)
48{
49 return 0;
50}
51
52int MsgQueue::Break() const
53{
54 return fSize>0 || fState!=kRun;
55}
56
57// --------------------------------------------------------------------------
58//
59// This is the thread which handles the processing.
60// As soon as a message is posted the fBreak flag is set (see PostMsg)
61// And as soon as the current action is finished the new action is executed
62// in this thread. This makes sure, that the calling program is not stalled.
63//
64void MsgQueue::Thread()
65{
66 std::unique_lock<std::mutex> lock(fMutex);
67
68 while (1)
69 {
70 while (fList.empty() && fState==kRun)
71 fCond.wait(lock);
72
73 if (fState==kAbort)
74 break;
75
76 if (fState==kStop && fList.empty())
77 break;
78
79 const auto &val = fList.front();
80 fSize--;
81
82 lock.unlock();
83 Proc(val.first, const_cast<char*>(val.second.data()));
84 lock.lock();
85
86 fList.pop_front();
87 }
88
89 fList.clear();
90 fSize = 0;
91
92 fState = kIdle;
93}
94
95
96// --------------------------------------------------------------------------
97//
98// Use this function to post a message.
99// mp can be a pointer to a data structure. size should be the size of it.
100// size bytes of this structure are copied and a pointer to the copy
101// is forwarded to the Proc function.
102//
103void *MsgQueue::PostMsg(int msg, void *mp, int size)
104{
105 const std::lock_guard<std::mutex> lock(fMutex);
106 if (fState==kIdle)
107 return false;
108
109 fSize++;
110 fList.emplace_back(msg, vector<char>(reinterpret_cast<char*>(mp),reinterpret_cast<char*>(mp)+size));
111
112 fCond.notify_one();
113
114 return 0;
115
116}
Note: See TracBrowser for help on using the repository browser.