Having a tough time learning ASIO. I'm trying to have one thread constantly listen for new file monitoring events (mthread) while another thread processes one task at a time (wthread). Somehow I'm still losing events that don't get placed on the task_queue and it would seem that once an event is lost, the file_handler callback for the dir_monitor stops working thereafter for good. So I'm having a few issues with my solution.

If I comment out the sleep() method below, then for some reason the first two lines that have to do with the dir_monitor immediately after the while loop quickly eat through all available memory and the program will soon crash within a minute or two. Leaving the sleep in keeps things stable, or maybe it just eats away so slowly I don't notice it.

Leaving sleep() in also has the problem of *I think* causing missed file events. The f_handler() function posts tasks that I create within the dir_monitor callback back to the main thread via the io_service.post(), but if its asleep, will it be able to place objects on the main processes task_queue? I think thats one point where I'm going wrong.

If anyone sees where I'm going wrong, any help much appreciated.

---
static queue<TaskObj *> task_queue;
boost::asio::io_service io_service;

void queue_task(TaskObj *task)
{
    // pass task back to main thread.
    task_queue.push(task);
}

void f_handler(const boost::system::error_code &ec, const boost::asio::dir_monitor_event &ev)
{
    TaskObj task = new TaskObj(...);

    // create task and place on queue by posting to main process
    io_service.post(boost::bind(queue_task, task));
}

int main(...) {
    boost::asio::io_service work_service;
    boost::asio::dir_monitor dm(io_service);

    dm.async_monitor(f_handler);

    // dir_monitor thread
    boost::thread mthread =
        boost::thread(boost::bind(&boost::asio::io_service::run,
        boost::ref(io_service)));

    // setup work to prevent premature exit
    shared_ptr<boost::asio::io_service::work>
        work(new boost::asio::io_service::work(work_service));

    // worker thread
    boost::thread wthread(boost::bind(&boost::asio::io_service::run,
        boost::ref(work_service)));
    wthread.detach();

    while (true) {
        io_service.reset();
        dm.async_monitor(f_handler);
        // losing all available memory from above two lines without the sleep() below

        // get first task off of queue and process in worker thread
        task = task_queue.front();
        // functor executed in seperate thread
        work_service.post(boost::bind(&TaskObj::do_it, task));

        sleep(3);
    }