AAO DRAMA/DRAMA2 C++ Interface
threadbasic.cpp
/* T H R E A D B A S I C
* Module name:
threadbasic.cpp
* Function:
Test the basic threading facilities of a DRAMA 2 task.
* Description:
Responds to the following commands
TEST - Basic threading example, action implemented
as a thread, which itself starts a subsidiary
thread. Both threads will wait for a kick, with
5 and 10 second timeouts.
EXIT - Cause this task to exit.
* Language:
C++
* Copyright (c) Australian Astronomical Observatory, 2014.
Not to be used for commercial purposes without permission.
No warranty of any form unless subject to a specific agreement.
* Support: Tony Farrell, AAO
* @(#) $Id: ACMM:Drama2/examples/threadbasic.cpp,v 1.45+ 22-Feb-2016 14:09:53+11 tjf $
*/
#include "drama.hh"
#include "drama/sds.hh"
#include <thread>
#include <iostream>
#include <typeinfo>
class Polymorphic {virtual void member(){}};
class TestAction;
static void SecondThread(TestAction *);
class TestAction : public drama::thread::TAction {
public:
TestAction(std::weak_ptr<drama::Task> theTask) : TAction(theTask) {}
~TestAction() {}
private:
void ActionThread(const drama::sds::Id &obeyArg) override {
#if 0
fprintf(stderr,"threadbasic::ActionThread() invoked, arg=%d, addr=%p\n",
(int)SdsIdType(obeyArg), (void *)(&obeyArg));
#endif
if (obeyArg)
{
std::string MyArgument;
obeyArg.Get("Argument1", &MyArgument);
MessageUser(std::string("Obey Argument is:") + MyArgument);
}
else
{
MessageUser("No argument to obey");
}
/*
* Send a message to the user. (Method of the ActionThread class)
*/
MessageUser("Starting second thread");
std::thread childThread(SecondThread, this);
MessageUser("Waiting for kick");
/*
* Create an sds::Id item. We need a std::shared_ptr<> to it, which
* is what IdPtr is
*/
drama::sds::IdPtr Arg{std::make_shared<drama::sds::Id>()};
/*
* Wait for a kick message, with a timeout of 5 seconds.
*
* We pass in our IdPtr item Arg above, so that
* we can get any argument to the message.
*
* WaitForKickTimeIn() returns true if the kick message was received,
* false for a timeout.
*/
if (WaitForKickTimeoutIn(5, &Arg))
{
MessageUser("First thread, received kick");
if (*Arg)
{
std::string MyArgument;
Arg->Get("Argument1", &MyArgument);
MessageUser(MyArgument);
}
}
else
{
MessageUser("First thread, wait for kick timed out");
}
MessageUser("First thread Waiting to join child thread");
childThread.join();
MessageUser("First thread, child has joined");
//DramaTHROW("Test of throw from thread");
//Polymorphic * pb = 0;
//typeid(*pb); // throws a bad_typeid exception
MessageUser("Thread completing");
outArg.Put("Argument1", "Completion Argument.");
SetReturnArg(&outArg);
#if 0
fprintf(stderr,"threadbasic::ActionThread() exiting\n");
#endif
}
};
static void SecondThread(TestAction *action)
{
action->MessageUser("Second thread running, sending trigger");
trigArg.Put("Argument1", "Hi there:");
trigArg.Put("Argument2", "Trigger from second thread");
action->SendTrigger(trigArg);
/*
* Create an sds::Id item. We need a std::shared_ptr<> to it, which
* is what IdPtr is
*/
drama::sds::IdPtr Arg{std::make_shared<drama::sds::Id>()};
/*
* Wait for a kick message, with a timeout of 5 seconds.
*
* We pass in our IdPtr item Arg above, so that
* we can get any argument to the message.
*
* WaitForKickTimeIn() returns true if the kick message was received,
* false for a timeout.
*/
if (action->WaitForKickTimeoutIn(10, &Arg))
{
action->MessageUser("Second thread, received kick.");
if (*Arg)
{
std::string MyArgument;
Arg->Get("Argument1", &MyArgument);
action->MessageUser(MyArgument);
}
}
else
{
action->MessageUser("Second thread, wait for kick time out.");
}
}
class ThreadBasic : public drama::Task {
private:
TestAction TestActionObj;
public:
ThreadBasic() : drama::Task("THREADBASIC"), TestActionObj(TaskPtr()) {
Add("TEST", drama::MessageHandlerPtr(&TestActionObj, drama::nodel()));
}
~ThreadBasic() {
}
};
int main()
{
try
{
// Make this program a DRAMA task named ticker
ThreadBasic task;
// Process DRAMA messages.
task.RunDrama();
}
catch (drama::Exception &e)
{
e.Print();
exit (e.statusAsSysExitCode());
}
catch (std::exception &e)
{
std::cerr << "std::exception thrown by task.RunDrama"
<< e.what()
<< std::endl;
exit(1);
}
return 0;
}

Click here for the DRAMA home page and here for the AAO home page.

For more information, contact tjf@aao.gov.au 

Generated on Mon Feb 22 2016 15:57:52 for AAO DRAMA/DRAMA2 C++ Interface by doxygen 1.8.10