Hi I'm implementing an application, serial RS232 communications centered, using boost in Windows. Many of the user actions are translated to ASCII commands to be sent to some serial devices connected to the serial ports, but as they are quite slow, I had to implement a command queue, so that as soon as a command gets its answer, it is cleared and the next one is sent, up to the end of the queue (of course). Using boost serial communication features, I realized that I needed an extra time-out, because the devices are real slow. So that this low speed doesn't lock up anything, the command queue runs in a separate thread and I would like another thread to run a timer, that could be activated when the command is send by the queue thread, and deactivated by the same thread if it detects an answer coming from the device in response to its command. If the timer is due, it should send a signal or call a callback function in the queue thread so it knows that the last command timed-out and it should re-send it again. All the queue things are OK (so it seems for now), I just need the timer. The ASIO timer is quite strange to me, I didn't manage to make it work. I have already seen the "timers" tutorials at boost web pages, and none have worked for me as expected. Any ideas / suggestions / snippets? Thanks a lot Francisco -- "If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have one idea and we exchange these ideas, then each of us will have two ideas." - George Bernard Shaw
The ASIO timer is quite strange to me, I didn't manage to make it work. I have already seen the "timers" tutorials at boost web pages, and none have worked for me as expected.
Any ideas / suggestions / snippets?
asio::deadline_timer usage is trivial, what problem did you encounter?
As far as I could understand, the deadline_timer just runs once, i.e.,
if I would like to use it multiple times, I have to instantiate new
ones everytime.
It needs to be turned on inside a separate thread, the command queue
one, when it sends a serial command, and if the answer arives before
the timer is due, it has to be turned off, again inside that separate
queue thread, so it doesn't hit the "resend".
So far I did manage to put it to work, but after a few serial
commands, some successfull and some timed-out, the timer associated
"service" crashes.
I don't know if I should use a "mutex", neither where to put it. I
found the documentation a bit frustrating.
Thanks again
On 26 mar, 10:33, Igor R
The ASIO timer is quite strange to me, I didn't manage to make it work. I have already seen the "timers" tutorials at boost web pages, and none have worked for me as expected.
Any ideas / suggestions / snippets?
asio::deadline_timer usage is trivial, what problem did you encounter? _______________________________________________ Boost-users mailing list Boost-us...@lists.boost.orghttp://lists.boost.org/mailman/listinfo.cgi/boost-users
As far as I could understand, the deadline_timer just runs once, i.e., if I would like to use it multiple times, I have to instantiate new ones everytime.
That is not true. You can use expires_at or expires_from_now to reschedule an existing timer. Notice that any pending timeouts will be cancelled when you reschedule the timer. You have to call async_wait again after you reschedule the timer.
It needs to be turned on inside a separate thread, the command queue one, when it sends a serial command, and if the answer arives before the timer is due, it has to be turned off, again inside that separate queue thread, so it doesn't hit the "resend".
Use the cancel function to cancel the timer. Your handler function will still be invoked, but the error code will be "operation cancelled" instead of "not an error."
So far I did manage to put it to work, but after a few serial commands, some successful and some timed-out, the timer associated "service" crashes.
That sounds like a scope problem. The timer object must exist as long as there are outstanding handlers. ~Dan
As far as I could understand, the deadline_timer just runs once, i.e., if I would like to use it multiple times, I have to instantiate new ones everytime.
It's absolutely incorrect. Did you see asio exmaples/reference? On expiration or cancellation the timer invokes its handler - in the thread(s) of its io_service. Then you can start the same timer again: //... timer.expires_from_now(boost::ptime::seconds(5)); time.async_wait(&handler); //... void handler() { // start it again: timer.expires_from_now(boost::ptime::seconds(10)); timer.async_wait(&handler); }
It needs to be turned on inside a separate thread, the command queue one, when it sends a serial command, and if the answer arives before the timer is due, it has to be turned off, again inside that separate queue thread, so it doesn't hit the "resend".
The timer itself is not thread-safe, i.e. you have to start/cancel it from the thread(s) of its io_service. The most convenient way to deal with it is to make your queue processing io_service-based -- then you can just supply the same io_service to the timer. If it's not possible, you can perform timer-related operations from your queue thread by re-posting them to the timer thread, no locking is needed: void doCancel() { timer.cancel(); } void cancelFromAnotherThread() { timer.get_io_service().post(&doCancel); } ...and when timer handler is invoked (on timer.io_service thread), you just have to synchronize an access to your queue data, if needed.
participants (4)
-
boost_newbie
-
Casimiro, Daniel C CIV NUWC NWPT
-
Francisco Ares
-
Igor R