I am trying to achieve synchronization operation for hardware devices controlled by my C++ code.
Suppose Two types of devices are there on which I can perform Open/Close
.
What I need to achieve is Open one type of device for Specified Duration
. Same is true for Second type Of device.
I have written code with boost::deadline_timer
:
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
class Test : public std::enable_shared_from_this <Test>
{
public:
Test() :io_(), timerOne_(io_),timerTwo_(io_){}
void Open(int num);
void Close(int num);
void TimedOpen(int num, int dur);
void Run();
private:
boost::asio::io_service io_;
boost::asio::deadline_timer timerOne_;
boost::asio::deadline_timer timerTwo_;
};
void Test::Open(int type)
{
std::cout << "Open for Number : " << type << std::endl;
}
void Test::Close(int type)
{
std::cout << "Close for Number : " << type << std::endl;
}
void Test::TimedOpen(int type, int dur)
{
switch (type)
{
case 1:
{
io_.reset();
auto fn = std::bind(&Test::Open, shared_from_this(), std::placeholders::_1);
fn(type);
timerOne_.expires_from_now(boost::posix_time::seconds(dur));
timerOne_.async_wait(std::bind(&Test::Close, shared_from_this(), type));
Run();
std::cout << "Function Exiting" << std::endl;
std::cout << "-----------------------------------------------" << std::endl;
return;
}
case 2:
{
io_.reset();
auto fn = std::bind(&Test::Open, shared_from_this(), std::placeholders::_1);
fn(type);
timerTwo_.expires_from_now(boost::posix_time::seconds(dur));
timerTwo_.async_wait(std::bind(&Test::Close, shared_from_this(), type));
Run();
std::cout << "Function Exiting" << std::endl;
std::cout << "-----------------------------------------------" << std::endl;
return;
}
}
}
void Test::Run()
{
boost::thread th(boost::bind(&boost::asio::io_service::run, &io_));
}
int main()
{
auto t = std::make_shared<Test>();
t->TimedOpen(1, 60);
t->TimedOpen(2, 30);
t->TimedOpen(1, 5);
t->TimedOpen(2, 2);
char line[128];
while (std::cin.getline(line, 128))
{
if (strcmp(line, "\n")) break;
}
return 0;
}
The Output is:
Open for Number : 1
Function Exiting
-----------------------------------------------
Open for Number : 2
Function Exiting
-----------------------------------------------
Open for Number : 1
Close for Number : 1
Function Exiting
-----------------------------------------------
Open for Number : 2
Close for Number : 2
Function Exiting
-----------------------------------------------
Close for Number : 2
Close for Number : 1
For timerOne_
It does not wait for previous wait
to expire i.e. as soon as t->TimedOpen(1, 5)
is executed the previous action t->TimedOpen(1, 60)
is cancelled.
So Close for Number : 1
appears in output without waiting for t->TimedOpen(1, 60)
.
What I want to achieve is that if multiple waits are encountered
for any type of timer
, all the operations should be queued i.e.
If I type:
t->TimedOpen(1, 60);
t->TimedOpen(1, 10);
t->TimedOpen(1, 5);
It should do TimedOpen Operation
for 60+10+5
seconds. Currently it does only for 5 secs. Also It should be non blocking i.e. I can not use wait() instead of async_wait()
.
How do I achieve it?
Summary:
My requirement is to schedule operations on a boost::deadline_timer()
i.e. multiple operations on it will be queued unless previous wait is expired.