Imported Upstream version 1.51.0
[platform/upstream/boost.git] / doc / html / boost_asio / example / services / logger_service.hpp
1 //
2 // logger_service.hpp
3 // ~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef SERVICES_LOGGER_SERVICE_HPP
12 #define SERVICES_LOGGER_SERVICE_HPP
13
14 #include <boost/asio.hpp>
15 #include <boost/thread/thread.hpp>
16 #include <boost/bind.hpp>
17 #include <boost/date_time/posix_time/posix_time.hpp>
18 #include <boost/noncopyable.hpp>
19 #include <boost/scoped_ptr.hpp>
20 #include <fstream>
21 #include <sstream>
22 #include <string>
23
24 namespace services {
25
26 /// Service implementation for the logger.
27 class logger_service
28   : public boost::asio::io_service::service
29 {
30 public:
31   /// The unique service identifier.
32   static boost::asio::io_service::id id;
33
34   /// The backend implementation of a logger.
35   struct logger_impl
36   {
37     explicit logger_impl(const std::string& ident) : identifier(ident) {}
38     std::string identifier;
39   };
40
41   /// The type for an implementation of the logger.
42   typedef logger_impl* impl_type;
43
44   /// Constructor creates a thread to run a private io_service.
45   logger_service(boost::asio::io_service& io_service)
46     : boost::asio::io_service::service(io_service),
47       work_io_service_(),
48       work_(new boost::asio::io_service::work(work_io_service_)),
49       work_thread_(new boost::thread(
50             boost::bind(&boost::asio::io_service::run, &work_io_service_)))
51   {
52   }
53
54   /// Destructor shuts down the private io_service.
55   ~logger_service()
56   {
57     /// Indicate that we have finished with the private io_service. Its
58     /// io_service::run() function will exit once all other work has completed.
59     work_.reset();
60     if (work_thread_)
61       work_thread_->join();
62   }
63
64   /// Destroy all user-defined handler objects owned by the service.
65   void shutdown_service()
66   {
67   }
68
69   /// Return a null logger implementation.
70   impl_type null() const
71   {
72     return 0;
73   }
74
75   /// Create a new logger implementation.
76   void create(impl_type& impl, const std::string& identifier)
77   {
78     impl = new logger_impl(identifier);
79   }
80
81   /// Destroy a logger implementation.
82   void destroy(impl_type& impl)
83   {
84     delete impl;
85     impl = null();
86   }
87
88   /// Set the output file for the logger. The current implementation sets the
89   /// output file for all logger instances, and so the impl parameter is not
90   /// actually needed. It is retained here to illustrate how service functions
91   /// are typically defined.
92   void use_file(impl_type& /*impl*/, const std::string& file)
93   {
94     // Pass the work of opening the file to the background thread.
95     work_io_service_.post(boost::bind(
96           &logger_service::use_file_impl, this, file));
97   }
98
99   /// Log a message.
100   void log(impl_type& impl, const std::string& message)
101   {
102     // Format the text to be logged.
103     std::ostringstream os;
104     os << impl->identifier << ": " << message;
105
106     // Pass the work of opening the file to the background thread.
107     work_io_service_.post(boost::bind(
108           &logger_service::log_impl, this, os.str()));
109   }
110
111 private:
112   /// Helper function used to open the output file from within the private
113   /// io_service's thread.
114   void use_file_impl(const std::string& file)
115   {
116     ofstream_.close();
117     ofstream_.clear();
118     ofstream_.open(file.c_str());
119   }
120
121   /// Helper function used to log a message from within the private io_service's
122   /// thread.
123   void log_impl(const std::string& text)
124   {
125     ofstream_ << text << std::endl;
126   }
127
128   /// Private io_service used for performing logging operations.
129   boost::asio::io_service work_io_service_;
130
131   /// Work for the private io_service to perform. If we do not give the
132   /// io_service some work to do then the io_service::run() function will exit
133   /// immediately.
134   boost::scoped_ptr<boost::asio::io_service::work> work_;
135
136   /// Thread used for running the work io_service's run loop.
137   boost::scoped_ptr<boost::thread> work_thread_;
138
139   /// The file to which log messages will be written.
140   std::ofstream ofstream_;
141 };
142
143 } // namespace services
144
145 #endif // SERVICES_LOGGER_SERVICE_HPP