ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
mthread.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2019 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
7// todo: add precomp everywhere
8
9#if !defined(HPP_AWORX_ALIB_THREADS_MODEL_MTHREAD)
11#endif
12#if ALIB_ENUMS
13# if !defined(HPP_ALIB_ENUMS_SERIALIZATION)
15# endif
16#endif
17
18#if !defined(ALIB_DOX) // todo remove
19
20
21namespace alib::threads::model {
22
23MThread::MThread(const String& pName)
24: Thread( pName )
25, stoppedFlag(false)
26{
27}
28
29MThread::~MThread()
30{
31 State curState= GetState();
32 if( curState == Thread::State::Unstarted )
33 {
34 ALIB_MESSAGE("ATHR", NString256( "Thread \"" ) << GetName()
35 << "\" is destructed, while it was never started" )
36 }
37 else if( curState != Thread::State::Terminated )
38 {
39 ALIB_MESSAGE("ATHR", NString256( "Thread \"" ) << GetName()
40 << "\" is destructed, while it is in state \""
41 << curState << '"' )
42 return;
43 }
44}
45
46void MThread::Stop()
47{
48 stoppedFlag= true;
49 cmdPipe.Push(MThread::InternalCommands::Stop, 10, nullptr, nullptr );
50}
51
52void MThread::Run()
53{
54 ALIB_MESSAGE("ATHR", NString256( "MThread \"") << GetName() << "\" is running" )
55
56 while(!stoppedFlag)
57 {
58 CmdPipe::Command cmd= cmdPipe.Pop();
59
60 // internal commands
61 if( cmd.cmd.IsEnumType<InternalCommands>() )
62 {
63 #if !ALIB_DEBUG
65 #endif
66 switch (cmd.cmd.Get<InternalCommands>())
67 {
68 case InternalCommands::Stop:
69 #if ALIB_DEBUG
70 ALIB_MESSAGE("ATHR", NString256("MThread \"") << GetName()
71 << "\" received stop command" )
72 if( stoppedFlag == false )
73 ALIB_ERROR("ATHR", NString256("MThread \"") << GetName()
74 << "\": Stop command in pipe, but stop flag not set")
75 #endif
76 break;
77
78
79 #if ALIB_DEBUG
80 case InternalCommands::NoCommand:
81 ALIB_ERROR("ATHR", "Illegal command 'NoCommand' received.")
82 break;
83 #endif
84 }
85 #if !ALIB_DEBUG
87 #endif
88
89 // that's it in respect to internal commands
90 continue;
91 }
92
93 // process external command
94 processCommand(cmd);
95 }
96
97 #if ALIB_DEBUG
98 NString256 msg( "MThread \""); msg << GetName() << "\" is stopping.";
99 if( cmdPipe.PeekSize() > 0 )
100 {
101 msg << ' ' << cmdPipe.PeekSize() << "commands still in pipe!" << NewLine();
102 for( int i= 0; i < std::min(10, cmdPipe.PeekSize()) ; ++i)
103 msg << " " << i << ": " << cmdPipe.PeekCmd(i).cmd << NewLine();
104 }
105 ALIB_MESSAGE( "ATHR", msg )
106 #endif
107}
108
109//--------------------------------------------------------------------------------------------------
110// MThread::CmdPipe
111//--------------------------------------------------------------------------------------------------
112void MThread::CmdPipe::Push(Enum cmd, int priority, Box data, Box data2)
113{
114 { ALIB_LOCK
115 // search the first element with equal or higher priority
116 std::list<Command>::iterator it= pipe.begin();
117 while(it != pipe.end())
118 {
119 if(priority <= (*it).priority)
120 break;
121 it++;
122 }
123
124 // insert before found
125 it= pipe.insert(it, Command(cmd,priority,data, data2));
126
127 // statistics
128 usageCounter++;
129 } // lock
130
131 // if consumer is sleeping then wake him up
132 Notify();
133}
134
135MThread::CmdPipe::Command MThread::CmdPipe::Pop()
136{
137 // threadsafe access to the pipe
138 Acquire(ALIB_CALLER_PRUNED);
139
140 // loop until we get a command (the Acquire after sleep is
141 // unsafe, therefore we have to loop as another thread may
142 // steal the message that waked us up meanwhile....
143 while(pipe.size()==0)
144 {
145 // no, -> sleep!
146 WaitForNotification();
147 Acquire(ALIB_CALLER_PRUNED);
148 #if ALIB_DEBUG
149 if( pipe.size() == 0)
150 ALIB_WARNING("ATHR", "Cmd pipe empty after wakeup" )
151 if( pipe.size() > 2)
152 ALIB_WARNING("ATHR", NString256("Cmd pipe growing to: ") << pipe.size() )
153 #endif
154 }
155
156 // get message
157 Command msg(pipe.back());
158 pipe.pop_back();
159
160 Release();
161
162 // log thread activity
163 return msg;
164}
165
166MThread::CmdPipe::Command MThread::CmdPipe::PeekCmd(int n)
167{
168 auto it= pipe.begin();
169 for( int i= 0; i < n ; ++i)
170 if( it!=pipe.end() )
171 ++it;
172 return it != pipe.end() ? *it : Command( InternalCommands::NoCommand, 0, nullptr, nullptr );
173}
174
175
176
177} // namespace [alib::threads::model]
178
179#endif // !defined(ALIB_DOX)
180
#define ALIB_WARNING(...)
Definition alib.hpp:981
#define ALIB_MESSAGE(...)
Definition alib.hpp:982
#define ALIB_WARNINGS_RESTORE
Definition alib.hpp:715
#define ALIB_ERROR(...)
Definition alib.hpp:980
#define ALIB_WARNINGS_ALLOW_SPARSE_ENUM_SWITCH
Definition alib.hpp:669
#define ALIB_LOCK
#define ALIB_CALLER_PRUNED
Definition alib.hpp:845
constexpr CString NewLine()
Definition cstring.hpp:528
threads::Thread Thread
Type alias in namespace alib.
Definition thread.hpp:390
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256> .