//-------------------------------------------
// HEADER
//-------------------------------------------
#include <functional>
#include <system_error>
#include <thread>
#include <boost/asio.hpp>
using boost::asio::io_service;
class service
{
public:
typedef std::function<void (const std::error_code&)> completion_handler;
service();
~service();
void start(completion_handler handle_start);
void stop(completion_handler handle_stop);
template <typename HandlerFunction>
void post(HandlerFunction perform_operation)
{
strand_.post(perform_operation);
}
private:
typedef std::shared_ptr<io_service> service_ptr;
static void run_service(service_ptr core_service);
service_ptr core_service_;
io_service::work* work_;
io_service::strand strand_;
std::thread runner_;
};
//-------------------------------------------
// TRANSLATION UNIT
//-------------------------------------------
#define BITCOIN_ASSERT BOOST_ASSERT
service::service()
: core_service_(std::make_shared<io_service>()),
strand_(*core_service_), work_(nullptr)
{
}
service::~service()
{
BITCOIN_ASSERT(work_ == nullptr);
core_service_->stop();
runner_.join();
}
void service::run_service(service_ptr core_service)
{
core_service->run();
std::cout << "service closed" << std::endl;
}
void service::start(completion_handler handle_start)
{
BITCOIN_ASSERT(work_ == nullptr);
work_ = new io_service::work(*core_service_);
runner_ = std::thread(&service::run_service, core_service_);
post(std::bind(handle_start, std::error_code()));
}
void service::stop(completion_handler handle_stop)
{
BITCOIN_ASSERT(work_ != nullptr);
delete work_;
work_ = nullptr;
post(std::bind(handle_stop, std::error_code()));
}
//-------------------------------------------
// TEST FILE
//-------------------------------------------
#include <iostream>
service* s = new service;
void foo()
{
std::cout << "foo called" << std::endl;
}
void bar()
{
std::cout << "bar called" << std::endl;
}
void handle_stop(const std::error_code& ec)
{
//s->post(foo);
delete s;
}
void stop()
{
std::cout << "stop called" << std::endl;
s->stop(handle_stop);
}
void begin(const std::error_code& ec)
{
std::cout << "Started" << std::endl;
s->post(foo);
s->post(bar);
s->post(stop);
}
int main()
{
s->start(begin);
std::cin.get();
return 0;
}