AAO DRAMA/DRAMA2 C++ Interface
DRAMA C++11 and later interface
task.hh
Go to the documentation of this file.
1#ifndef _DRAMA2_TASK_INC
2#define _DRAMA2_TASK_INC
3
13/*
14 * History:
15 07-Jan-2014 - TJF - Original version
16 23-Mar-2018 - TJF - Add CheckLockTaken static method;
17 18-Jan-2018 - TJF - Add SeparateThreadRunsDrama() method and properly support
18 this by maintaining IDs for both the thread that created
19 DRAMA and that which is running the message loop.
20 Replace GetTaskThreadId() by GetTaskCreThreadId() and
21 GetTaskRunThreadId() as part of this.
22
23 * The above ID is for Doxygen, this one has the format ACMM is looking for.
24 * "@(#) $Id$"
25 */
26
27#include "DitsTypes.h"
28#include <string>
29#include <DitsSys.h>
30
32#include "drama/spawnable.hh"
33#include "drama/logger.hh"
34#include "drama/fmt/format.h"
35
36#include <thread>
37
38/* These two lines allows us to format thread::id values with fmt::format. See https://fmt.dev/11.0/api/#stdostream-support */
39#include "drama/fmt/ostream.h"
40template <> struct fmt::formatter<std::thread::id> : ostream_formatter {};
41
42#include <mutex>
43#include <set>
44
45#include <memory> // For shared_ptr.
46#include <iostream>
47#include <deque>
48#include <type_traits>
49#include <functional>
50
51/*
52 * This file uses DOXYGEN comments - the following is placed into the
53 * index page. note that the @file block says to include the typedefs,
54 * functions etc from this file into the documentation.
55 */
56
61namespace drama {
62
63 class Task;
64
65 namespace thread {
66 /*
67 * These declarations are needed to allow
68 * AddTA(const std::string &name, thread::ThreadActionFunction func) to
69 * be defined.
70 *
71 * See threadaction.hh for full details of these.
72 */
73 class TAction; // Class used for threaded action implementations
74 /* Function used to implementation actions */
75 using ThreadActionFunction = std::function<void (TAction *, const sds::Id &)> ;
76 /* Function from threadaction.cpp used to wrap up using a function
77 * to implement a threaded action
78 */
79 void AddActionFunction(Task *,
80 const std::string &name,
82 const std::string &descr);
83
84 } // namespace thread;
85
92 struct nodel
93 {
96 void operator()(void const *) const
97 {
98 }
99 };
100
101
107 struct TransEvtInfo {
110 std::string entryName;
111 std::string loadErrText;
112 bool complete;
114 };
115
126 class OrphanDetails : public TransEvtInfo {
127
128 public:
141 sds::IdPtr arg,
145 argument(arg),
146 path (thePath),
147 transId(tid) {
148 }
149
150
151 };
152 /* @internal
153 * A queue of OrphanDetails.
154 *
155 * A std::queue would be a better representation of this
156 * then "std::deque", but we do want to clear the queue and
157 * std::queue does not support that.
158 */
159 typedef std::deque<OrphanDetails> OrphanDetailsQueue;
160
161
162
163
166 typedef std::shared_ptr<MessageHandler> MessageHandlerPtr;
168#ifndef RUNNING_DOXYGEN
169
170 /*
171 * If defined, we use our own sub-class of a std::recursive_mutex
172 * such that we can implement checks around use of locks. This
173 * is the normal default and DRAMA is not well tested without
174 * it being defined
175 */
176#define DRAMA2_LOCK_DEBUG
177
178 /*
179 * If defined, then we create a task specific file which records
180 * lock calls. This is rather complicated, but might be useful in
181 * tracking deadlock situations. The files written are named
182 * DramaLock-<pid>.log.
183 */
184//#define DRAMA2_LOCK_DEBUG2
185
186#endif // defined(RUNNING_DOXYGEN)
187
188#ifdef DRAMA2_LOCK_DEBUG2
189
190 /*
191 * If DEBUG2 is enabled, we need DEBUG.
192 */
193#ifndef DRAMA2_LOCK_DEBUG
194#define DRAMA2_LOCK_DEBUG
195#endif
196 /*
197 * The DRAMA2_TASK_CPP macro is set by the task.cpp file. We use
198 * this to trigger a warning if DEBUG2 debugging is enabled.
199 */
200#ifdef DRAMA2_TASK_CPP
201#warning "Lock debugging level 2 enabled - will slow things down"
202#endif
203
204 /* This macro allows to do stuff only when this logging is enabled*/
205#define DRAMA2_LOCK_DEBUG2_Only(_A_) _A_
206#else // !defined(DRAMA2_LOCK_DEBUG2)
207#define DRAMA2_LOCK_DEBUG2_Only(_A_) /*_A_*/
208
209#endif // !defined(DRAMA2_LOCK_DEBUG2)
210
211#ifdef DRAMA2_LOCK_DEBUG
212 /* Wrapper for a recursive timed mutex which allows us to
213 * work out if it has been taken and if so, by who
214 *
215 */
216 //class LockWithInfo : public std::recursive_timed_mutex {
217 class LockWithInfo : public std::recursive_mutex {
218 private:
219 bool _taken; /* Has the mutex been taken */
220 unsigned _count; /* Number of times a thread has taken it*/
221 std::thread::id _takenBy;/* Thread which has it */
222#ifdef DRAMA2_LOCK_DEBUG2
223 static std::ofstream _debugFile; /* Lock log file, process specific */
224 static unsigned _lockCount; /* How many locks in the process */
225 char _code = '_'; /* This lock's prefix */
226 /* Write time and thread details for the debug file to a stream */
227 void TimeNowAndThreadToStream(std::ostream &stream);
228#endif
229 public:
238 LockWithInfo(const std::string &whichLock);
239 /*
240 * Destroy the lock. If DEBUG2 is defined, and this
241 * is the last lock, close the log file.
242 */
244
245 /* Overload parent class lock() method, do our
246 * stuff after taking the lock.
247 */
248 void lock();
249 /* Overload parent class try_lock() method, do our
250 * stuff after taking the lock.
251 */
252 bool try_lock() noexcept;
253
254 /* Overload parent class unlock() method, do our
255 * stuff before releasing the lock.
256 */
257 void unlock();
258 /*
259 * Ensure the current thread has taken the lock. Throw
260 * an exception if not.
261 *
262 * func, file and lineNum are used in constructing the
263 * exception so you know the source of the call.
264 *
265 * @param func Name of the function where the call was made
266 * @param file Name of the file in which the call was made
267 * @param lineNum Line number where the call was made.
268 */
269 void CheckTaken(const std::string &func,
270 const std::string &file,
271 const int lineNum) const;
272 /*
273 * Ensure the current thread has taken the lock and that
274 * it is the specified thread. Throw an exception if not.
275 *
276 * This is typically used to ensure the DRAMA thread is the
277 * current thread and has the lock.
278 *
279 * func, file and lineNum are used in constructing the
280 * exception so you know the source of the call.
281 *
282 * @param t The thread which should be the current thread.
283 * @param func Name of the function where the call was made
284 * @param file Name of the file in which the call was made
285 * @param lineNum Line number where the call was made
286 */
287 void CheckTakenBy(std::thread::id t,
288 const std::string &func,
289 const std::string &file,
290 const int lineNum) const;
291 /*
292 * Ensure the current thread has taken the lock and that
293 * it is the DRAMA task thread. Throw an exception if not.
294 *
295 * This is typically used to ensure the DRAMA thread is the
296 * current thread and has the lock.
297 *
298 * func, file and lineNum are used in constructing the
299 * exception so you know the source of the call.
300 *
301 * @param task Reference to the drama task.
302 * @param func Name of the function where the call was made.
303 * @param file Name of the file in which the call was made.
304 * @param lineNum Line number where the call was made.
305 */
306 void CheckTakenBy(std::weak_ptr<Task> task,
307 const std::string &func,
308 const std::string &file,
309 const int lineNum) const;
310 /*
311 * Ensure the current thread has taken the lock and that
312 * it is the DRAMA task thread. Throw an exception if not.
313 *
314 * This is typically used to ensure the DRAMA thread is the
315 * current thread and has the lock.
316 *
317 * func, file and lineNum are used in constructing the
318 * exception so you know the source of the call.
319 *
320 * @param task Reference to the drama task.
321 * @param func Name of the function where the call was made.
322 * @param file Name of the file in which the call was made
323 * @param lineNum Line number where the call was made.
324 */
325 void CheckTakenBy(Task * task,
326 const std::string &func,
327 const std::string &file,
328 const int lineNum) const;
329
330 /*
331 * Ensure the current thread has not taken the lock. Throws
332 * an exception if it has.
333 *
334 * func, file and lineNum are used in constructing the
335 * exception so you know the source of the call.
336 *
337 * @param func Name of the function where the call was made.
338 * @param file Name of the file in which the call was made.
339 * @param lineNum Line number where the call was made.
340 */
341 void CheckNotTakenBy(const std::string func,
342 const std::string &file,
343 const int lineNum) const;
344 /*
345 * Show the status of the lock - output to std::cerr.
346 */
347 void Show() const;
348 }; // class LockWithInfo
349#endif /* if defined DRAMA2_LOCK_DEBUG */
350
367 public:
368 /*
369 * Constructor
370 */
381 virtual int RunDramaHasExited() = 0;
382
393 virtual bool JoinThreads(std::chrono::steady_clock::time_point until) = 0;
394
395 virtual ~RunDramaExitNotifier() {}
396 };
397
425 class Task : public std::enable_shared_from_this<Task> {
426 public:
436#ifdef DRAMA2_LOCK_DEBUG
437 typedef LockWithInfo mutexType;
438#else
439 typedef std::recursive_timed_mutex mutexType;
440#endif
441 //typedef std::mutex mutexType;
444 typedef std::lock_guard<mutexType> guardType;
447 typedef std::unique_lock<mutexType> uniqueLockType;
448
454 typedef drama::Request (Task::*ActionMethod)(drama::MessageHandler *mh);
461 typedef void (Task::*ThreadActionMethod)(
462 drama::thread::TAction *taction,
463 const drama::sds::Id& id);
464
465 private:
466 std::string _name;
467
468 std::thread::id _taskCreThreadId; // Id of thread that created task.
469 std::thread::id _taskRunThreadId; // Id of thread running the message loop.
470 /*
471 * This mutex is the main lock around DRAMA operations when
472 * running in threaded mode.
473 */
474 mutexType _dramaLock;
475
476 /*
477 * A set of the RunDRamaExitNotifier objects.
478 */
479 typedef std::set<RunDramaExitNotifier *> RunDramaExitNotifierSetType;
480
482 /*
483 * This mutex locks DRAMA message notifications. Unclear if it is
484 * actually needed. We don't take the _dramaLock when waiting
485 * for messages, since we want other threads to be able to
486 * execute DRAMA calls.
487 */
488 mutexType _dramaMsgNotifyLock;
489
493 OrphanDetailsQueue _orphanQueue;
494
499 static void HandleDitsOrphan(StatusType *status);
500 /*
501 * Unfortunately, DitsPutOrphanHandler() does not allow
502 * a clientData item to be passed to the handler routine.
503 * We must maintain the address of our task in a static
504 * so we can invoke methods on the right task. Fortunately,
505 * we can only have one task running - the DRAMA registration
506 * process ensures that.
507 */
508 static Task *orphanTask;
509
510 /*
511 * Handle messages for orphaned transactions. Non-static
512 * method invoked by HandleDitsOrphan.
513 */
514 void HandleOrphanMes(StatusType *status);
515
516
517 /* Invoked when a DRAMA message is available, processes it.
518 */
519 void ProcessMessage(long *exitFlag, StatusType *status);
520
521 /*
522 * A vector of notifiers to be invoked when the RunDrama() exits.
523 */
524 RunDramaExitNotifierSetType _loopExitNotifiers;
525
526 /*
527 * The task logger. Only used if opened.
528 */
529 std::unique_ptr<logging::Logger> _taskLogger;
530
531 /*
532 * Add an action to the task. Unlike the pubic interfaces, takes
533 * a spawnable argument and an ActionHandlerPtr.
534 *
535 * This is invoked by all the public interfaces to add an
536 * action to the DRAMA2 task.
537 */
538 virtual void AddAction(const std::string &name, bool spawnable,
539 ActionHandlerPtr obj,
540 const std::string &descr);
541
542 /*
543 * Shared pointer to self. This for std::shared<Task> operator.
544 */
545 std::shared_ptr<Task> _sharedSelf = nullptr;
546 /*
547 * Handling of shared pointers, as returned by TaskPtr() has
548 * been initialised.
549 */
550 bool _sharedInit = false;
551 /*
552 * Will be set true if it is found by TaskPtr() that our object
553 * already has a shared pointer.
554 */
555 bool _amShared = false;
556
557 /*
558 * If this is set true, then we don't complain if a separate thread
559 * is being used to run DRAMA.
560 */
561 bool _sepThreadToRunDramaOK = false;
562
563
564
567 Task& operator=(const Task &rhs) = delete;
570 Task(const Task &source) = delete;
571
572 /* Method used to implement AddMth */
573 void AddMethodAction(
574 const std::string &actionName,
576 const std::string &descr);
577 /* Method used to implement AddMthThd */
578 void AddMethodAction(
579 const std::string &actionName,
581 const std::string &descr);
582
583
584
585
586 protected:
614 virtual void OrphanHandler(const OrphanDetails &details);
615
616 public:
617
618 static const int DefBufSize;
619 static const int DefSelfBufSize;
643 Task(const std::string &name, int buffer=DefBufSize,
644 int flags=0, int selfBytes=DefSelfBufSize);
648 virtual void RunDrama();
649
661 _sepThreadToRunDramaOK = true;
662 }
663
664
680 virtual void Add(const std::string &name, MessageHandlerPtr obj,
681 const std::string &descr ="") {
682 AddAction(name, false, obj,descr);
683 }
684
699 virtual void Add(const std::string &name, MessageHandler *obj,
700 const std::string &descr ="") {
702 }
703
720 virtual void Add(const std::string &name, MessageReceiveFunction func,
721 const std::string &descr ="") {
722
723 Add(name, std::make_shared<MessageHandlerViaFunctor>(func), descr);
724 }
725
742 /* For some reason, this is ambigous with the above in some cases, so we need a different name */
743 virtual void AddTA(const std::string &name, thread::ThreadActionFunction func,
744 const std::string &descr ="") {
745 thread::AddActionFunction(this, name, func, descr);
746 }
748
765 virtual void AddSpawnable(const std::string &name, SpawnablePtr obj,
766 const std::string &descr ="") {
767 AddAction(name, true, obj, descr);
768 }
769
784 virtual void AddSpawnable(const std::string &name, Spawnable *obj,
785 const std::string &descr ="") {
786 AddAction(name, true, SpawnablePtr(obj), descr);
787 }
788
807 template <typename T>
808 void AddMth(
809 const std::string &actionName,
810 T method,
811 const std::string &descr ="") {
812
813 //The important thing here is that we must allow a sub-class
814 // of drama::Task to invoke specify its own methods. This
815 // cast allows that to happen. The cast will fail if
816 // the method doesn't have the right format.
817 AddMethodAction(actionName,
818 static_cast<drama::Task::ActionMethod>(method), descr);
819 }
839 template <typename T>
840 void AddMthThd(
841 const std::string &actionName,
842 T method,
843 const std::string &descr ="") {
844
845 //The important thing here is that we must allow a sub-class
846 // of drama::Task to invoke specify its own methods. This
847 // cast allows that to happen. The cast will fail if
848 // the method doesn't have the right format.
849 AddMethodAction(actionName,
851 }
859 mutexType & Lock() {
860 return _dramaLock;
861 }
871 std::thread::id GetTaskCreThreadId() const {
872 return _taskCreThreadId;
873 }
883 std::thread::id GetTaskRunThreadId() const {
884 return _taskRunThreadId;
885 }
899 return *_taskLogger;
900 }
901
906 std::string TaskName() const {
907 return _name;
908 }
909
916 void NotifyOnRunDramaExit(RunDramaExitNotifier *notifier);
921 void CancelNotifyOnRunDramaExit(RunDramaExitNotifier *notifier);
922
932 void AddOrphanToQueue(const OrphanDetails &orphan) {
933#ifdef DRAMA2_LOCK_DEBUG // If debugging, check we have the lock.
934 Lock().CheckTaken(__func__, __FILE__,__LINE__);
935#endif
936 _orphanQueue.push_front(orphan);
937 }
938
939
963 std::weak_ptr<Task> TaskPtr() {
964
965 guardType guard(_dramaLock);
966 /*
967 * This function initialises internal items on the
968 * first time through - can't be done in constructor
969 * as shared_from_this() will always fail there.
970 *
971 * Note - shared_from_this() comes from std::enable_shared_from_this,
972 * which we inherit.
973 */
974 //std::thread::id thisThread = std::this_thread::get_id();
975
976 //std::cerr << thisThread << "::TaskPtr() invoked, ";
977 if (_sharedInit)
978 {
979 //std::cerr << "_shareInit is true, ";
980 if (_amShared)
981 {
982 //std::cerr << "_amShared, " << std::endl;
983 return shared_from_this();
984 }
985 else
986 {
987 //std::cerr << "using _sharedSelf, " << std::endl;
988 return _sharedSelf;
989 }
991 // Only get here if not initialised
992 try
993 {
994 //std::cerr << "trying for shared_from_this(), ";
995
996 std::shared_ptr<Task> p = shared_from_this();
997 // If we have not thrown, then we are a shared pointer object.
998 _sharedInit = true;
999 _amShared = true;
1000 //std::cerr << "got it, am shared" << std::endl;
1001 return p;
1002 }
1003 /*
1004 * According to http://en.cppreference.com's page on std::enable_shared_from_this,
1005 * this is actually undefined behaviour this is not already a shared pointer, until
1006 * c++17. It does at least seem to work for gnu C++ and Clang++ at c++11.
1007 */
1008 catch (const std::bad_weak_ptr &e)
1009 {
1010
1011 //std::cerr << "Am not created from a shared, will init _sharedSelf" << std::endl;
1012
1013 _sharedSelf = std::shared_ptr<Task>(this, drama::nodel());
1014 _amShared = false;
1015 _sharedInit = true;
1016 return _sharedSelf;
1017 }
1018
1019 }
1020
1031 template <typename T>
1032 std::shared_ptr<T> TaskPtrAs() {
1033 return std::dynamic_pointer_cast<T>(std::shared_ptr<Task>(TaskPtr()));
1034 }
1035
1046 virtual double GetJoinTimeout() const;
1047
1052 virtual ~Task();
1053
1089 void Signal(const std::string &name, sds::Id *arg=nullptr, void *data=nullptr);
1090
1127 void Signal(long int index, sds::Id *arg=nullptr, void *data=nullptr);
1128
1129
1145 virtual void _MessageUser(const std::string &text) const;
1146
1147
1148
1170 void SetDetails(const std::string &descr, int type = 0);
1171
1180 std::string GetTaskDescription(const std::string &taskName) const;
1181
1190 int GetTaskType(const std::string &taskName) const;
1191
1192
1193 /*
1194 * Ensure the current thread has taken the DRAMA task lock.
1195 * Throw an exception if not.
1196 *
1197 * This won't do anything unless DRAMA was compiled with
1198 * the DRAMA2_LOCK_DEBUG macro defined.
1199 *
1200 * This method is static and uses an internal static variable
1201 * to find the drama::Task object.
1202 *
1203 * func, file and lineNum are used in constructing the
1204 * exception so you know the source of the call.
1205 *
1206 * @param func Name of the function where the call was made
1207 * @param file Name of the file in which the call was made
1208 * @param lineNum Line number where the call was made.
1209 */
1210 static void CheckLockTaken(const std::string &func,
1211 const std::string &file,
1212 const int lineNum) ;
1213
1214
1215
1216 }; // Class Task.
1246 template <class TaskClass, typename... ParamTypes >
1248
1249 static_assert(std::is_base_of<Task, TaskClass>(), "TaskClass must be a sub-class of drama::task");
1250
1251 try
1252 {
1253 /* Create and run the task */
1254 TaskClass task(std::forward<ParamTypes>(taskPars)...);
1255 task.RunDrama();
1256 }
1257 catch (const drama::Exception &e)
1258 {
1259 std::cerr << "CreateRunDramaTask():drama::Exception thrown"
1260 << std::endl
1261 << e.toString(true) // Outputs all the exception details.
1262 << std::endl;
1263
1264 exit (e.statusAsSysExitCode());
1265 }
1266 catch (const std::exception &e)
1267 {
1268 std::cerr << "CreateRunDramaTask():std::exception thrown."
1269 << std::endl
1270 << e.what()
1271 << std::endl;
1272 exit(1);
1273 }
1274 catch (...)
1275 {
1276 std::cerr << "CreateRunDramaTask():Non-standard exception thrown."
1277 << std::endl;
1278 throw; // Rethrow to get any core dump etc
1279
1280 }
1281 } // CreateRunDramaTask()
1282#if 1
1311 template <class TaskClass>
1312 void CreateRunDramaTask() {
1313
1314 static_assert(std::is_base_of<Task, TaskClass>(), "TaskClass must be a sub-class of drama::task");
1315 try
1316 {
1317 /* Create and run the task */
1319 task.RunDrama();
1320 }
1321 catch (const drama::Exception &e)
1322 {
1323 std::cerr << "CreateRunDramaTask():drama::Exception thrown"
1324 << std::endl
1325 << e.toString(true) // Outputs all the exception details.
1326 << std::endl;
1327
1328 exit (e.statusAsSysExitCode());
1329 }
1330 catch (const std::exception &e)
1331 {
1332 std::cerr << "CreateRunDramaTask():std::exception thrown."
1333 << std::endl
1334 << e.what()
1335 << std::endl;
1336 exit(1);
1337 }
1338 catch (...)
1340 std::cerr << "CreateRunDramaTask():Non-standard excepton thrown."
1341 << std::endl;
1342 throw; // Rethrow to get any core dump etc
1343
1344 }
1345 } // CreateRunDramaTask()
1346#endif
1347} // namespace drama
1348
1349#endif
An Exception class for exceptions thrown by DRAMA V2 classes.
Definition exception.hh:183
A class which implements a DRAMA Message Handler.
Definition messagehandler.hh:141
DitsPathType path
The DITS path the transaction was sent to.
Definition task.hh:157
OrphanDetails(TransEvtInfo evtInfo, sds::IdPtr arg, DitsPathType thePath, DitsTransIdType tid)
Construct an OrphanDetails item.
Definition task.hh:167
sds::IdPtr argument
The Argument to the transaction.
Definition task.hh:156
DitsTransIdType transId
The DITS Transaction ID.
Definition task.hh:158
Structure which maintains details on orphan transactions.
Definition task.hh:153
Class used by Obey and Kick handlers to indicate rescheduling requirements.
Definition request.hh:78
virtual bool JoinThreads(std::chrono::steady_clock::time_point until)=0
Invoked by DRAMA when the run loop exists.
virtual int RunDramaHasExited()=0
Invoked by DRAMA when the run loop exits.
Class used to arrange for notifications when the RunDrama exits.
Definition task.hh:393
A class which implements a Spawnable DRAMA Message Handler.
Definition spawnable.hh:84
static const int DefBufSize
Default (minimum) global buffer size.
Definition task.hh:645
std::shared_ptr< T > TaskPtrAs()
Returns a shared pointer to the task, dynamically cast to the template type.
Definition task.hh:1059
virtual void Add(const std::string &name, MessageHandlerPtr obj, const std::string &descr="")
Add an action to the task.
Definition task.hh:707
virtual void AddTA(const std::string &name, thread::ThreadActionFunction func, const std::string &descr="")
Add an threaded action to the task.
Definition task.hh:770
Task(const std::string &name, int buffer=DefBufSize, int flags=0, int selfBytes=DefSelfBufSize)
Create a new DRAMA task of the specified name.
virtual void AddSpawnable(const std::string &name, SpawnablePtr obj, const std::string &descr="")
Add a spawnable action to the task.
Definition task.hh:792
void(Task::* ThreadActionMethod)(drama::thread::TAction *taction, const drama::sds::Id &id)
This type is for methods of the task which implement threaded actions.
Definition task.hh:488
void Signal(long int index, sds::Id *arg=nullptr, void *data=nullptr)
Trigger the rescheduling of an action, specifying the index of the action.
std::unique_lock< mutexType > uniqueLockType
Defines the type of a unique_lock type using our mutex type.
Definition task.hh:474
virtual void RunDrama()
Run the DRAMA message loop in the current thread.
virtual double GetJoinTimeout() const
Get the thread join timeout.
std::string GetTaskDescription(const std::string &taskName) const
Get the description of a task.
std::string TaskName() const
Return task name.
Definition task.hh:933
void AddMth(const std::string &actionName, T method, const std::string &descr="")
Add an action to the task, implemented by a method.
Definition task.hh:835
mutexType & Lock()
Reference the DRAMA Task lock.
Definition task.hh:886
std::thread::id GetTaskRunThreadId() const
Return the thread ID of the thread running RunDrama()
Definition task.hh:910
virtual void Add(const std::string &name, MessageReceiveFunction func, const std::string &descr="")
Add an action to the task.
Definition task.hh:747
std::recursive_timed_mutex mutexType
Defines the type of our mutex.
Definition task.hh:466
void AddOrphanToQueue(const OrphanDetails &orphan)
Add an orphan to the queue of orphans to be processed before we next look at the DRAMA message queue.
Definition task.hh:959
void SeparateThreadRunsDrama()
Tell the task we are expecting a separate thread to run the DRAMA message loop.
Definition task.hh:687
logging::Logger & Logger()
Reference to DRAMA 2 Logger.
Definition task.hh:925
int GetTaskType(const std::string &taskName) const
Get the type of a task.
void Signal(const std::string &name, sds::Id *arg=nullptr, void *data=nullptr)
Trigger the rescheduling of an action, specifing the name of the action.
virtual void _MessageUser(const std::string &text) const
Use DRAMA to send a message to the user.
virtual void AddSpawnable(const std::string &name, Spawnable *obj, const std::string &descr="")
Add an action to the task.
Definition task.hh:811
void CancelNotifyOnRunDramaExit(RunDramaExitNotifier *notifier)
Cancel notification for when the DRAMA RunDrama() exits.
std::lock_guard< mutexType > guardType
Defines the type of a lock guard using our mutex type.
Definition task.hh:471
virtual void OrphanHandler(const OrphanDetails &details)
Orphan transaction handler.
void AddMthThd(const std::string &actionName, T method, const std::string &descr="")
Add an action to the task, implemented by a method.
Definition task.hh:867
virtual void Add(const std::string &name, MessageHandler *obj, const std::string &descr="")
Add an action to the task.
Definition task.hh:726
std::weak_ptr< Task > TaskPtr()
Returns a weak pointer to the task.
Definition task.hh:990
std::thread::id GetTaskCreThreadId() const
Return the thread ID of the thread on which the Task object was created.
Definition task.hh:898
static const int DefSelfBufSize
Default (minimum) self buffer size.
Definition task.hh:646
virtual ~Task()
Destructor - shut down the DRAMA task.
drama::Request(Task::* ActionMethod)(drama::MessageHandler *mh)
This type is for methods the task which implement actions.
Definition task.hh:481
void SetDetails(const std::string &descr, int type=0)
Set task details.
void NotifyOnRunDramaExit(RunDramaExitNotifier *notifier)
Arrange notification for when the DRAMA RunDrama() exits.
A class which implements a DRAMA task.
Definition task.hh:452
Implementation of a Class supporting Logging within an AAO DRAMA Task.
Definition logger.hh:790
A C++ Interface to the handling SDS structures.
Definition sds.hh:428
A class which implements a DRAMA Action with runs a thread.
Definition threadaction.hh:204
Header file for a DRAMA 2 class which implements Logging.
DRAMA 2 include file - Message Handler class definition.
std::shared_ptr< Id > IdPtr
A shared pointer for sds::Id items.
Definition sds.hh:3613
std::function< void(TAction *, const sds::Id &)> ThreadActionFunction
Type used for functions specified drama::Task::Add().
Definition task.hh:102
void CreateRunDramaTask()
Create and run a DRAMA task, with standard exception handling.
Definition task.hh:1339
std::shared_ptr< Spawnable > SpawnablePtr
This type is used for passing Spawnable object addresses around.
Definition spawnable.hh:200
EntryCode
Entry type code - indicates the type of a DRAMA event.
Definition entryinfo.hh:67
@ Signal
Signal message received.
std::shared_ptr< MessageHandler > MessageHandlerPtr
This type is used for passing MessageHandler object addresses around.
Definition messagehandler.hh:96
void CheckLockTaken(const std::string func, const std::string &file, const int lineNum)
Ensure the current thread has taken the DRAMA task lock.
std::function< Request(MessageHandler *)> MessageReceiveFunction
Type used for functions specified to drama::MessageHandler::PutObeyHandler(), drama::MessageHandler::...
Definition messagehandler.hh:106
The drama namespace contains all the classes, types etc of the DRAMA 2 implementation.
Definition drama.hh:99
DRAMA 2 include file - Spawnable action implementation.
DitsBulkInfoType bulkInfo
Details on bulk data transfer.
Definition task.hh:140
EntryCode entryReason
Reason for entry.
Definition task.hh:135
StatusType entryStatus
Entry status value.
Definition task.hh:136
std::string entryName
Name with entry.
Definition task.hh:137
std::string loadErrText
Load error text
Definition task.hh:138
bool complete
IS transaction complete.
Definition task.hh:139
Structure is used to store details about a DRAMA reschedule message relating to a transaction,...
Definition task.hh:134
void operator()(void const *) const
Invoked to delete the memory used.
Definition task.hh:123
Declare an operator to be used as a deletion operator by std::shared_ptr.
Definition task.hh:120