Boosters,

Ok -- turns out I really didn't know what I was doing.
And I really didn't want strand at all-
I'm still fuzzy on strand.
But here's the code for what I really did want.
And the thread group is handling the Handlers properly.

Now my question is...
Why is a deadline timer the way it is?
What's it good for?
Why isn't a delay/timer like a wrapper, that you can give a function object to, and then push that into the io_service queue with a delay?
So you could do something like,
io_s.post(deadline_timer(boost::posix_time::milliseconds(100), &f));
?

- Zola



#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/ref.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <vector>
namespace asio = boost::asio;

int const num_threads = 10;
std::vector<boost::thread*> tv(num_threads);
boost::mutex tv_mutex;
boost::mutex io_mutex;

class Test
{
  public:
   
    Test(asio::io_service& io_s, unsigned int n)
    :
        io_s(io_s),
        n(n),
        f(boost::bind(&Test::print, this))
    {
        io_s.post(f);
    }
   
    void print()
    {
        if (n >= 0)
        {
            {
                boost::mutex::scoped_lock lock(io_mutex);
                std::cout << "(thread=" << thread_num() << ") ";
                std::cout << "Timer: " << n << std::endl;
            }
           
            {
                boost::mutex::scoped_lock lock(m_mutex);
                io_s.post(f);
                --n;
            }
           
            boost::xtime xt;
            boost::xtime_get(&xt, boost::TIME_UTC);
            xt.sec += 1;
            boost::thread::sleep(xt);
        }
    }
   
    int thread_num()
    {
        boost::thread t;
       
        for (int i=0; i<num_threads; ++i)
        {
            boost::mutex::scoped_lock lock(tv_mutex);
            if (tv[i] && (*tv[i] == t))
            {
                return i;
            }
        }
       
        return -1;
    }
   
  private:
   
    asio::io_service& io_s;
    unsigned int n;
    boost::function<void()> f;
    boost::mutex m_mutex;
};

int main()
{
    asio::io_service io_s;
    Test t(io_s, 1000);
   
    boost::thread_group threads;
    for (int i=0; i<num_threads; ++i)
    {
        boost::mutex::scoped_lock lock(tv_mutex);
        tv[i] = threads.create_thread(boost::bind(&asio::io_service::run, boost::ref(io_s)));
    }
    threads.join_all();
}