Boost logo

Boost Users :

Subject: Re: [Boost-users] ASIO, boost::function in VC7.1
From: Igor R (boost.lists_at_[hidden])
Date: 2009-04-26 07:09:14


> I am wondering what are  the issues involved when calling
> deadline_timer::async_wait, deadline_timer::cancel for a timer that is
> associated with an io_service object when io_service::run has already
> started in a different thread? Or in other words following the point " the
> io_service may be being run in a background thread that is launched prior to
> the application's asynchronous operations"  in
> http://www.boost.org/doc/libs/1_38_0/doc/html/boost_asio/reference/io_service.html,
> how do I launch asynch operations using an io_service that has already being
> run?

Since the io_service itself is thread-safe, there's no problem to
attach asio objects to it from another thread. I.e., you can create
deadline_timer's from within the main thread, just like you do in your
code. However, cancelling the timers might cause race-condition,
because io_service's thread might try to access the timer at the very
same moment.
To avoid this you can apply the pattern, which is widely used in asio examples:

private:
void IntervalEvent::syncCancel()
{
  m_timer.cancel();
}
public:
void IntervalEvent::cancel()
{
  // m_timer.cancel(); instead of cancelling here, just re-post this
action to io_service thread(s)

  // invoke another member function, in case of a complex action
  m_timer.get_io_service().post(bind(&IntervalEvent::syncCancel, this));

  // or, in case of simple action, just construct it on-the-fly:
  m_timer.get_io_service().post(bind(&deadline_timer::cancel,
boost::ref(m_timer)));

}

Any access to a running timer/socket can be made this way.
As for initial async_wait(), I can't see any potential
race-conditions, so I guess it's ok to do this from the main thread.

> In the particular example below, the member function onIncrement of the
> class Counter is not thread safe, but since the io_service::run is running
> on a one thread, only one handler will be invoked on the thread that runs
> io_service::run, so implicitly there is a serialization of access, correct?

Counter::onIncrement is invoked from one thread, that's true. But
writing there to std::cout is not thread-safe anyway, because
std::cout is not exclusively owned by Counter.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net