#include #include #include #include #include #include #include #include #include namespace services { // ----------------- io_service ------------------- class logger_service : public boost::asio::io_service::service { public: static boost::asio::io_service::id id; struct logger_impl { explicit logger_impl(const std::string& ident) : identifier(ident) {} std::string identifier; }; typedef logger_impl* impl_type; logger_service(boost::asio::io_service& io_service) : boost::asio::io_service::service(io_service), work_io_service_(), work_(new boost::asio::io_service::work(work_io_service_)), work_thread_(new boost::thread( boost::bind(&boost::asio::io_service::run, &work_io_service_))) {} ~logger_service() { work_.reset(); if (work_thread_) work_thread_->join(); } void shutdown_service() {} impl_type null() const { return 0; } void create(impl_type& impl, const std::string& identifier) { impl = new logger_impl(identifier); } void destroy(impl_type& impl) { delete impl; impl = null(); } void use_file(impl_type& /*impl*/, const std::string& file) { work_io_service_.post(boost::bind( &logger_service::use_file_impl, this, file)); } void log(impl_type& impl, const std::string& message) { std::ostringstream os; os << impl->identifier << ": " << message; work_io_service_.post(boost::bind( &logger_service::log_impl, this, os.str())); } private: void use_file_impl(const std::string& file) { ofstream_.close(); ofstream_.clear(); ofstream_.open(file.c_str()); } void log_impl(const std::string& text) { ofstream_ << text << std::endl; } boost::asio::io_service work_io_service_; boost::scoped_ptr work_; boost::scoped_ptr work_thread_; std::ofstream ofstream_; }; boost::asio::io_service::id logger_service::id; // ------------- io_object ------------ template class basic_logger : private boost::noncopyable { public: typedef Service service_type; typedef typename service_type::impl_type impl_type; explicit basic_logger(boost::asio::io_service& io_service, const std::string& identifier) : service_(boost::asio::use_service(io_service)), impl_(service_.null()) { service_.create(impl_, identifier); } ~basic_logger() { service_.destroy(impl_); } boost::asio::io_service& get_io_service() { return service_.get_io_service(); } void use_file(const std::string& file) { service_.use_file(impl_, file); } void log(const std::string& message) { service_.log(impl_, message); } private: service_type& service_; impl_type impl_; }; } // namespace services typedef services::basic_logger logger; int main() { boost::asio::io_service io_service; boost::asio::signal_set signals(io_service); logger l(io_service, "test"); signals.add(SIGINT); signals.async_wait(boost::bind(&boost::asio::io_service::stop, &io_service)); l.use_file("test.log"); l.log("do log"); io_service.run(); return 0; }