async_loop.h / async_loop.cpp

async_loop.h

#ifndef ASYNCLOOP_H
#define ASYNCLOOP_H

// AVOID ERROR BECAUSE OF swprintf
#undef __STRICT_ANSI__
// #define FOR WIN7. CAN'T FIND sdkddkver.h ON MINGW
#define _WIN32_WINNT 0x0601
#include <boost/asio.hpp>
#include <boost/function.hpp>

namespace util
{

enum TaskState { TASK_DONE, TASK_WORKING };

void AsyncLoopSocket(boost::function<TaskState()> doWork,
    boost::asio::ip::tcp::socket& sock, bool isRead);
void AsyncLoopTimer(boost::function<TaskState()> doWork,
    boost::asio::deadline_timer& dTimer, int millisecs);

} // namespace util

#endif // ASYNCLOOP_H

async_loop.cpp

#include "asyncloop.h"

#include <boost/bind.hpp>
using boost::bind;

#include <iostream>
using std::cerr;
using std::endl;

namespace util
{

void AsyncLoopSocket(boost::function<TaskState()> doWork,
    boost::asio::ip::tcp::socket& sock, bool isRead)
{
    // IF WE'VE STOPPED THE LOOP, DON'T REARM THE HANDLER
    if (sock.get_io_service().stopped())
    {
        return;
    }

    TaskState st = doWork();

    if (st == TASK_WORKING)
    {
        if (isRead)
        {
            sock.async_read_some(boost::asio::null_buffers(),
                bind(AsyncLoopSocket, doWork, boost::ref(sock), isRead));
        }
        else
        {
            sock.async_write_some(boost::asio::null_buffers(),
                bind(AsyncLoopSocket, doWork, boost::ref(sock), isRead));
        }

        return;
    }

    // WORK IS OVER, SIGNAL A STOP
    sock.get_io_service().stop();
}

void AsyncLoopTimer(boost::function<TaskState()> doWork,
    boost::asio::deadline_timer& dTimer, int millisecs)
{
    TaskState st = doWork();

    if (st == TASK_WORKING)
    {
        dTimer.expires_from_now(boost::posix_time::milliseconds(millisecs));
        dTimer.async_wait(boost::bind(AsyncLoopTimer, doWork, 
            boost::ref(dTimer), millisecs));
    }

    // WORK IS OVER; NOTHING TO DO, AS THE TIMER IS NOT REARMED
}

} // namespace util

No comments:

Post a Comment