AAO DRAMA/DRAMA2 C++ Interface
DRAMA C++11 and later interface
threaduface.hh
Go to the documentation of this file.
1#ifndef _DRAMA2_THREADUFACE_INC
2#define _DRAMA2_THREADUFACE_INC
17/*
18 * History:
19 07-Apr-2014 - TJF - Original version
20 18-Jan-2018 - TJF - TUface constructor now takes a name for log entries associated
21 with the thread running the uface context.
22
23
24 * The above ID is for Doxygen, this one has the format ACMM is looking for.
25 * "@(#) $Id$"
26 */
28#include "drama/thread.hh"
29#include <thread>
30#include <queue>
31#include <deque>
32#include <map>
33#include <chrono>
34#include <future>
35#include <condition_variable>
36namespace drama {
37
38 namespace thread {
39
53 void SignalDramaToExit(std::weak_ptr<Task> dramaTask,
65 // TMessHandler and RunDramaExitNotifier are abstract only.
66 class TUface : public TMessHandler, public RunDramaExitNotifier {
67
68 private:
69 /*
70 * Pointer to the DRAMA task we are part of.
71 * The pointer is const - we never change it after the constructor.
72 * The task pointed to is NOT const - since we can operate on it.
73 */
74 std::weak_ptr<Task> _theTask;
75 EntryInfo _entryInfo; // UFACE entry details.
76
77 /*
78 * A set of points to UFACE which are used by the logger only
79 * via RegisterThreadNoDramaCtx()
80 */
81 static std::set<TUface *> _loggerOnly;
82
83 public:
84
100 TUface(std::weak_ptr<Task> dramaTask,
101 const std::string &logThreadName="TUface::TUface");
106 virtual ~TUface();
107
108
120 virtual int RunDramaHasExited() override;
137 virtual bool JoinThreads(std::chrono::steady_clock::time_point until) override;
138
139 public:
140
145 std::shared_ptr<Task> GetTask() const override {
146 return std::shared_ptr<Task>(_theTask);
148
163 void MessageUser(const std::string &text) const override;
186 template<typename... Types>
187 void MessageUser(const char *format, Types... args) {
188
189 /*
190 * Our approach is to write the output to a string, via
191 * SafePrintf(), then output that in one operation. Since
192 * std::ostream devices will then do the output in one operation.
193 */
194 std::stringstream sstrm;
196 MessageUser(sstrm.str());
197
198
199 }
200
201
225
226
232 Task::mutexType & Lock() const override;
233
242 Dits___CurActType GetMessageContext() const override;
243
248 virtual const EntryInfo & GetEntry() const {
249 return _entryInfo;
250 }
261
262 /*
263 * We save the address in a set.
264 */
265 if (! ___LoggerOnlyUFACEItem(this))
266 _loggerOnly.insert(this);
267 }
278 static bool ___LoggerOnlyUFACEItem(TUface *pnt);
279
280 private:
281 Dits___CurActType _ufaceCtxDetails;
282
283 /*
284 * A map which contains all the events we are waiting on.
285 * (one per subsidiary thread).
286 */
287 WaitEventMapType _waitEventMap;
288
289
290 void MessageReceived();
291 void ProcessSubsidiaryMessage();
292 /*
293 * Invoked by DRAMA when a UFACE message is received.
294 */
295 static void UfaceMessageHandler(StatusType *);
296
297 /*
298 * Invoke when the thread is ending (TUface destructor invoked
299 * - will make any outstanding events into orphans.
300 */
301 void OrphanOutstandingEvents();
302
303
304 protected:
308 void GrabEntryInfo() {
309 _entryInfo.SetFromDits();
310 }
311
312
321 void ClearWait(bool complete) override;
322
323 /*
324 * Return a pointer to the event details for the specified thread.
325 */
326 WaitEventDetails *FindWaitEventDetails(std::thread::id)
327 override;
328
329
337 WaitEventDetails * WaitForTransactionStart() {
338 std::thread::id threadId(std::this_thread::get_id());
339 auto mapItem = _waitEventMap.find(threadId);
340 assert (mapItem != _waitEventMap.end());
341 return (&(mapItem->second));
342 }
343
352 const WaitEventData &details,
353 TransEvtInfo * const eventInfo,
354 sds::IdPtr * const arg) {
355
356
357 *eventInfo = details.eventInfo;
358 /*
359 * If the user wants the argument, return it.
360 */
361 if (arg)
362 {
363 *arg = details.arg;
365 // Should complain here (throw exception?) if queue not empty
366 ClearWait(details.eventInfo.complete);
367
368 }
369
370
371 };
372
373 } // namespace thread
374} // namespace drama
375
376#endif
void SetFromDits()
Grab the information of interest from DITS.
Definition entryinfo.hh:123
The EntryInfo class is used to access details about a DRAMA message event (and entry to an action).
Definition entryinfo.hh:106
A Class which provides access to DRAMA's message sending facilities.
Definition path.hh:689
Class used to arrange for notifications when the RunDrama exits.
Definition task.hh:382
std::recursive_timed_mutex mutexType
Defines the type of our mutex.
Definition task.hh:455
This interface class must be implemented by classes which have threads waiting for messages.
Definition thread.hh:308
static bool ___LoggerOnlyUFACEItem(TUface *pnt)
Indicate if logger only UFACE item created when Logger::RegisterThreadNoDramaCtx() was invoked (Actua...
void MessageUser(const std::string &text) const override
Use DRAMA to send a message to the user.
void WaitForTransactionFinish(const WaitEventData &details, TransEvtInfo *const eventInfo, sds::IdPtr *const arg)
The wait for transaction operation has finished - tidy up.
Definition threaduface.hh:378
std::shared_ptr< Task > GetTask() const override
Get a reference to the DRAMA task we are part of.
Definition threaduface.hh:172
void SetupWaitEvent(DitsTransIdType tid, drama::Path *pathObj) override
Sets up a wait event for this thread.
virtual const EntryInfo & GetEntry() const
Return the entry details.
Definition threaduface.hh:275
TUface(std::weak_ptr< Task > dramaTask, const std::string &logThreadName="TUface::TUface")
Create a DRAMA action/message handler object which runs a thread when the Obey message is received.
Task::mutexType & Lock() const override
Reference the DRAMA Task lock.
virtual ~TUface()
TUface destructor.
void MessageUser(const char *format, Types... args)
Use DRAMA to send a message to the user - safe format.
Definition threaduface.hh:214
virtual bool JoinThreads(std::chrono::steady_clock::time_point until) override
Invoked when the drama::task::RunDrama() loop exits.
void ClearWait(bool complete) override
Clear the thread' waiting flag in _waitEventMap.
WaitEventDetails * WaitForTransactionStart()
Initiate waiting for a transaction and return a pointer to the item the wait event details.
Definition threaduface.hh:364
virtual int RunDramaHasExited() override
Invoked when the drama::task::RunDrama() loop exits.
Dits___CurActType GetMessageContext() const override
Get the DRAMA Context associated with the UFACE event.
void ___SetLoggerOnlyUFACEItem()
Indicate that this UFACE item is for a thread which invoked Logger::RegisterThreadNoDramaCtx() withou...
Definition threaduface.hh:287
void GrabEntryInfo()
Fetch the DRAMA Entry information.
Definition threaduface.hh:335
A class which allows threads running in a User Interface or similar environments to send DRAMA messag...
Definition threaduface.hh:93
DRAMA 2 include file - Message Handler class definition.
std::shared_ptr< Id > IdPtr
A shared pointer for sds::Id items.
Definition sds.hh:3318
void SignalDramaToExit(std::weak_ptr< Task > dramaTask, StatusType exitStatus=STATUS__OK)
Signal to DRAMA that this task should exit.
void CreateRunDramaTask()
Create and run a DRAMA task, with standard exception handling.
Definition task.hh:1322
void SafePrintf(std::ostream &ostream, const char *str)
Safe formatted write to a stream.
The drama namespace contains all the classes, types etc of the DRAMA 2 implementation.
Definition drama.hh:93
Structure is used to store details about a DRAMA reschedule message relating to a transaction,...
Definition task.hh:128
DRAMA 2 include file - Code common to DRAMA 2 features supporting threading.