AAO DRAMA/DRAMA2 C++ Interface
tocker.cpp
/* T O C K E R
* Module name:
TOCKER
* Function:
A simple DRAMA message sending test program.
* Description:
Finds the program TICKER and sends the TICK message too
it <n> times. It then sends the EXIT message to it and then
exits itself.
<n> is set on the command line. Defaults to 100.
On exit, print stats.
* 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/tocker.cpp,v 1.45+ 22-Feb-2016 14:09:53+11 tjf $
*/
static const char *rcsId="@(#) $Id: ACMM:Drama2/examples/tocker.cpp,v 1.45+ 22-Feb-2016 14:09:53+11 tjf $";
static void *use_rcsId = (0 ? (void *)(&use_rcsId) : (void *) &rcsId);
#include "drama.hh"
#include "drama/path.hh"
#include <iostream>
#include <chrono>
// This thread is used to send the messages. This is a DRAMA2 UFACE thread.
void MyThread(drama::Task *task, unsigned count)
{
// Use this type to maintain clock.
typedef std::chrono::high_resolution_clock::time_point myClock;
try
{
// We must create a ufaceHandler at this point. Only then can
// we send DRAMA messages.
drama::thread::TUface ufaceHandler(task->TaskPtr());
// Find the path to the TICKER program, loading it if needed.
drama::Path ticker(task->TaskPtr(), "TICKER", "", "./ticker");
ticker.GetPath(&ufaceHandler);
// Grab time now.
myClock initClock = std::chrono::high_resolution_clock::now();
for (unsigned i = 0; i < count ; ++i)
{
ticker.Obey(&ufaceHandler, "TICK");
}
// Determine time since first TICK.
std::chrono::duration<double> duration =
std::chrono::high_resolution_clock::now() - initClock;
ticker.Obey(&ufaceHandler, "EXIT");
// Output times - as per DramaDits/tocker.c
std::cout << "TOCKER:Total time for "
<< count
<< " ticks is "
<< std::fixed << std::showpoint
<< std::setw(6)
<< std::setprecision(2)
<< duration.count()
<< "s, Ave Time = "
<< std::setprecision(4)
<< (duration.count()*1000.0/count)
<< "ms"
<< std::endl;
}
catch (...)
{
// Ensure the DRAMA loop exits and re-throw the exception.
throw;
}
}
class Tocker : public drama::Task {
private:
std::future<void> _ufaceThreadFuture;
public:
Tocker(unsigned count) : drama::Task("TOCKER") {
/*
* By constructing one of these, we block all signals whilst
* the thread is being created, to avoid race conditions. The
* thread will block signals itself once it starts running. The
* destructor restores the signal mask.
*/
drama::thread::SignalBlocker threadSignalBlocker;
/*
* Launch the thread.
*/
_ufaceThreadFuture = std::async(std::launch::async, MyThread, this, count);
}
/*
* Used to wait for the thread started in the constructor to exit.
* Timeout in seconds supplied
*/
void WaitThreadExit(unsigned seconds) {
if (_ufaceThreadFuture.wait_for(std::chrono::seconds(seconds)) !=
std::future_status::ready)
{
DramaTHROW(DRAMA2__THREAD_TIMEOUT,
"UFACE Thread did not complete");
}
_ufaceThreadFuture.get(); // Will throw if async thread did.
}
~Tocker() {
}
};
int main(int argc, char *argv[])
{
int count = 0;
bool delay_loop_start = false;
if (argc > 1)
count = atoi(argv[1]);
if (count < 0)
delay_loop_start = true;
if (count <= 0) count = 100;
try
{
// Make this program a DRAMA task named TOCKER
Tocker task(count);
// Process DRAMA messages.
// If the use specified a negative count, then this is enabled.
// What we are testing is a problem that used to happen if
// the running of RunDrama() occurred after the first message
// was sent. All we really need is to force a context switch
// such that MyThread is invoked.
if (delay_loop_start)
{
fprintf(stderr,"Delaying start of DRAMA loop to check that works\n");
std::this_thread::sleep_for (std::chrono::seconds(1));
}
task.RunDrama();
// Wait for the threads to exit.
task.WaitThreadExit(3);
}
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