• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // io_service.hpp
3 // ~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 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 ASIO_IO_SERVICE_HPP
12 #define ASIO_IO_SERVICE_HPP
13 
14 
15 #include "asio/detail/config.hpp"
16 #include <cstddef>
17 #include <stdexcept>
18 #include <typeinfo>
19 #include "asio/async_result.hpp"
20 #include "asio/detail/noncopyable.hpp"
21 #include "asio/detail/wrapped_handler.hpp"
22 #include "asio/error_code.hpp"
23 
24 #if   defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX)    || defined(__osf__)
25 # include "asio/detail/signal_init.hpp"
26 #endif
27 
28 #include "asio/detail/push_options.hpp"
29 
30 namespace asio {
31 
32 class io_service;
33 template <typename Service> Service& use_service(io_service& ios);
34 template <typename Service> void add_service(io_service& ios, Service* svc);
35 template <typename Service> bool has_service(io_service& ios);
36 
37 namespace detail {
38   typedef class task_io_service io_service_impl;
39   class service_registry;
40 } // namespace detail
41 
42 /// Provides core I/O functionality.
43 /**
44  * The io_service class provides the core I/O functionality for users of the
45  * asynchronous I/O objects, including:
46  *
47  * @li asio::ip::tcp::socket
48  * @li asio::ip::tcp::acceptor
49  * @li asio::ip::udp::socket
50  * @li asio::deadline_timer.
51  *
52  * The io_service class also includes facilities intended for developers of
53  * custom asynchronous services.
54  *
55  * @par Thread Safety
56  * @e Distinct @e objects: Safe.@n
57  * @e Shared @e objects: Safe, with the specific exceptions of the reset() and
58  * notify_fork() functions. Calling reset() while there are unfinished run(),
59  * run_one(), poll() or poll_one() calls results in undefined behaviour. The
60  * notify_fork() function should not be called while any io_service function,
61  * or any function on an I/O object that is associated with the io_service, is
62  * being called in another thread.
63  *
64  * @par Concepts:
65  * Dispatcher.
66  *
67  * @par Synchronous and asynchronous operations
68  *
69  * Synchronous operations on I/O objects implicitly run the io_service object
70  * for an individual operation. The io_service functions run(), run_one(),
71  * poll() or poll_one() must be called for the io_service to perform
72  * asynchronous operations on behalf of a C++ program. Notification that an
73  * asynchronous operation has completed is delivered by invocation of the
74  * associated handler. Handlers are invoked only by a thread that is currently
75  * calling any overload of run(), run_one(), poll() or poll_one() for the
76  * io_service.
77  *
78  * @par Effect of exceptions thrown from handlers
79  *
80  * If an exception is thrown from a handler, the exception is allowed to
81  * propagate through the throwing thread's invocation of run(), run_one(),
82  * poll() or poll_one(). No other threads that are calling any of these
83  * functions are affected. It is then the responsibility of the application to
84  * catch the exception.
85  *
86  * After the exception has been caught, the run(), run_one(), poll() or
87  * poll_one() call may be restarted @em without the need for an intervening
88  * call to reset(). This allows the thread to rejoin the io_service object's
89  * thread pool without impacting any other threads in the pool.
90  *
91  * For example:
92  *
93  * @code
94  * asio::io_service io_service;
95  * ...
96  * for (;;)
97  * {
98  *   try
99  *   {
100  *     io_service.run();
101  *     break; // run() exited normally
102  *   }
103  *   catch (my_exception& e)
104  *   {
105  *     // Deal with exception as appropriate.
106  *   }
107  * }
108  * @endcode
109  *
110  * @par Stopping the io_service from running out of work
111  *
112  * Some applications may need to prevent an io_service object's run() call from
113  * returning when there is no more work to do. For example, the io_service may
114  * be being run in a background thread that is launched prior to the
115  * application's asynchronous operations. The run() call may be kept running by
116  * creating an object of type asio::io_service::work:
117  *
118  * @code asio::io_service io_service;
119  * asio::io_service::work work(io_service);
120  * ... @endcode
121  *
122  * To effect a shutdown, the application will then need to call the io_service
123  * object's stop() member function. This will cause the io_service run() call
124  * to return as soon as possible, abandoning unfinished operations and without
125  * permitting ready handlers to be dispatched.
126  *
127  * Alternatively, if the application requires that all operations and handlers
128  * be allowed to finish normally, the work object may be explicitly destroyed.
129  *
130  * @code asio::io_service io_service;
131  * auto_ptr<asio::io_service::work> work(
132  *     new asio::io_service::work(io_service));
133  * ...
134  * work.reset(); // Allow run() to exit. @endcode
135  *
136  * @par The io_service class and I/O services
137  *
138  * Class io_service implements an extensible, type-safe, polymorphic set of I/O
139  * services, indexed by service type. An object of class io_service must be
140  * initialised before I/O objects such as sockets, resolvers and timers can be
141  * used. These I/O objects are distinguished by having constructors that accept
142  * an @c io_service& parameter.
143  *
144  * I/O services exist to manage the logical interface to the operating system on
145  * behalf of the I/O objects. In particular, there are resources that are shared
146  * across a class of I/O objects. For example, timers may be implemented in
147  * terms of a single timer queue. The I/O services manage these shared
148  * resources.
149  *
150  * Access to the services of an io_service is via three function templates,
151  * use_service(), add_service() and has_service().
152  *
153  * In a call to @c use_service<Service>(), the type argument chooses a service,
154  * making available all members of the named type. If @c Service is not present
155  * in an io_service, an object of type @c Service is created and added to the
156  * io_service. A C++ program can check if an io_service implements a
157  * particular service with the function template @c has_service<Service>().
158  *
159  * Service objects may be explicitly added to an io_service using the function
160  * template @c add_service<Service>(). If the @c Service is already present, the
161  * service_already_exists exception is thrown. If the owner of the service is
162  * not the same object as the io_service parameter, the invalid_service_owner
163  * exception is thrown.
164  *
165  * Once a service reference is obtained from an io_service object by calling
166  * use_service(), that reference remains usable as long as the owning io_service
167  * object exists.
168  *
169  * All I/O service implementations have io_service::service as a public base
170  * class. Custom I/O services may be implemented by deriving from this class and
171  * then added to an io_service using the facilities described above.
172  */
173 class io_service
174   : private noncopyable
175 {
176 private:
177   typedef detail::io_service_impl impl_type;
178 
179 public:
180   class work;
181   friend class work;
182 
183   class id;
184 
185   class service;
186 
187   class strand;
188 
189   /// Constructor.
190   ASIO_DECL io_service();
191 
192   /// Constructor.
193   /**
194    * Construct with a hint about the required level of concurrency.
195    *
196    * @param concurrency_hint A suggestion to the implementation on how many
197    * threads it should allow to run simultaneously.
198    */
199   ASIO_DECL explicit io_service(std::size_t concurrency_hint);
200 
201   /// Destructor.
202   /**
203    * On destruction, the io_service performs the following sequence of
204    * operations:
205    *
206    * @li For each service object @c svc in the io_service set, in reverse order
207    * of the beginning of service object lifetime, performs
208    * @c svc->shutdown_service().
209    *
210    * @li Uninvoked handler objects that were scheduled for deferred invocation
211    * on the io_service, or any associated strand, are destroyed.
212    *
213    * @li For each service object @c svc in the io_service set, in reverse order
214    * of the beginning of service object lifetime, performs
215    * <tt>delete static_cast<io_service::service*>(svc)</tt>.
216    *
217    * @note The destruction sequence described above permits programs to
218    * simplify their resource management by using @c shared_ptr<>. Where an
219    * object's lifetime is tied to the lifetime of a connection (or some other
220    * sequence of asynchronous operations), a @c shared_ptr to the object would
221    * be bound into the handlers for all asynchronous operations associated with
222    * it. This works as follows:
223    *
224    * @li When a single connection ends, all associated asynchronous operations
225    * complete. The corresponding handler objects are destroyed, and all
226    * @c shared_ptr references to the objects are destroyed.
227    *
228    * @li To shut down the whole program, the io_service function stop() is
229    * called to terminate any run() calls as soon as possible. The io_service
230    * destructor defined above destroys all handlers, causing all @c shared_ptr
231    * references to all connection objects to be destroyed.
232    */
233   ASIO_DECL ~io_service();
234 
235   /// Run the io_service object's event processing loop.
236   /**
237    * The run() function blocks until all work has finished and there are no
238    * more handlers to be dispatched, or until the io_service has been stopped.
239    *
240    * Multiple threads may call the run() function to set up a pool of threads
241    * from which the io_service may execute handlers. All threads that are
242    * waiting in the pool are equivalent and the io_service may choose any one
243    * of them to invoke a handler.
244    *
245    * A normal exit from the run() function implies that the io_service object
246    * is stopped (the stopped() function returns @c true). Subsequent calls to
247    * run(), run_one(), poll() or poll_one() will return immediately unless there
248    * is a prior call to reset().
249    *
250    * @return The number of handlers that were executed.
251    *
252    * @throws asio::system_error Thrown on failure.
253    *
254    * @note The run() function must not be called from a thread that is currently
255    * calling one of run(), run_one(), poll() or poll_one() on the same
256    * io_service object.
257    *
258    * The poll() function may also be used to dispatch ready handlers, but
259    * without blocking.
260    */
261   ASIO_DECL std::size_t run();
262 
263   /// Run the io_service object's event processing loop.
264   /**
265    * The run() function blocks until all work has finished and there are no
266    * more handlers to be dispatched, or until the io_service has been stopped.
267    *
268    * Multiple threads may call the run() function to set up a pool of threads
269    * from which the io_service may execute handlers. All threads that are
270    * waiting in the pool are equivalent and the io_service may choose any one
271    * of them to invoke a handler.
272    *
273    * A normal exit from the run() function implies that the io_service object
274    * is stopped (the stopped() function returns @c true). Subsequent calls to
275    * run(), run_one(), poll() or poll_one() will return immediately unless there
276    * is a prior call to reset().
277    *
278    * @param ec Set to indicate what error occurred, if any.
279    *
280    * @return The number of handlers that were executed.
281    *
282    * @note The run() function must not be called from a thread that is currently
283    * calling one of run(), run_one(), poll() or poll_one() on the same
284    * io_service object.
285    *
286    * The poll() function may also be used to dispatch ready handlers, but
287    * without blocking.
288    */
289   ASIO_DECL std::size_t run(asio::error_code& ec);
290 
291   /// Run the io_service object's event processing loop to execute at most one
292   /// handler.
293   /**
294    * The run_one() function blocks until one handler has been dispatched, or
295    * until the io_service has been stopped.
296    *
297    * @return The number of handlers that were executed. A zero return value
298    * implies that the io_service object is stopped (the stopped() function
299    * returns @c true). Subsequent calls to run(), run_one(), poll() or
300    * poll_one() will return immediately unless there is a prior call to
301    * reset().
302    *
303    * @throws asio::system_error Thrown on failure.
304    */
305   ASIO_DECL std::size_t run_one();
306 
307   /// Run the io_service object's event processing loop to execute at most one
308   /// handler.
309   /**
310    * The run_one() function blocks until one handler has been dispatched, or
311    * until the io_service has been stopped.
312    *
313    * @return The number of handlers that were executed. A zero return value
314    * implies that the io_service object is stopped (the stopped() function
315    * returns @c true). Subsequent calls to run(), run_one(), poll() or
316    * poll_one() will return immediately unless there is a prior call to
317    * reset().
318    *
319    * @return The number of handlers that were executed.
320    */
321   ASIO_DECL std::size_t run_one(asio::error_code& ec);
322 
323   /// Run the io_service object's event processing loop to execute ready
324   /// handlers.
325   /**
326    * The poll() function runs handlers that are ready to run, without blocking,
327    * until the io_service has been stopped or there are no more ready handlers.
328    *
329    * @return The number of handlers that were executed.
330    *
331    * @throws asio::system_error Thrown on failure.
332    */
333   ASIO_DECL std::size_t poll();
334 
335   /// Run the io_service object's event processing loop to execute ready
336   /// handlers.
337   /**
338    * The poll() function runs handlers that are ready to run, without blocking,
339    * until the io_service has been stopped or there are no more ready handlers.
340    *
341    * @param ec Set to indicate what error occurred, if any.
342    *
343    * @return The number of handlers that were executed.
344    */
345   ASIO_DECL std::size_t poll(asio::error_code& ec);
346 
347   /// Run the io_service object's event processing loop to execute one ready
348   /// handler.
349   /**
350    * The poll_one() function runs at most one handler that is ready to run,
351    * without blocking.
352    *
353    * @return The number of handlers that were executed.
354    *
355    * @throws asio::system_error Thrown on failure.
356    */
357   ASIO_DECL std::size_t poll_one();
358 
359   /// Run the io_service object's event processing loop to execute one ready
360   /// handler.
361   /**
362    * The poll_one() function runs at most one handler that is ready to run,
363    * without blocking.
364    *
365    * @param ec Set to indicate what error occurred, if any.
366    *
367    * @return The number of handlers that were executed.
368    */
369   ASIO_DECL std::size_t poll_one(asio::error_code& ec);
370 
371   /// Stop the io_service object's event processing loop.
372   /**
373    * This function does not block, but instead simply signals the io_service to
374    * stop. All invocations of its run() or run_one() member functions should
375    * return as soon as possible. Subsequent calls to run(), run_one(), poll()
376    * or poll_one() will return immediately until reset() is called.
377    */
378   ASIO_DECL void stop();
379 
380   /// Determine whether the io_service object has been stopped.
381   /**
382    * This function is used to determine whether an io_service object has been
383    * stopped, either through an explicit call to stop(), or due to running out
384    * of work. When an io_service object is stopped, calls to run(), run_one(),
385    * poll() or poll_one() will return immediately without invoking any
386    * handlers.
387    *
388    * @return @c true if the io_service object is stopped, otherwise @c false.
389    */
390   ASIO_DECL bool stopped() const;
391 
392   /// Reset the io_service in preparation for a subsequent run() invocation.
393   /**
394    * This function must be called prior to any second or later set of
395    * invocations of the run(), run_one(), poll() or poll_one() functions when a
396    * previous invocation of these functions returned due to the io_service
397    * being stopped or running out of work. After a call to reset(), the
398    * io_service object's stopped() function will return @c false.
399    *
400    * This function must not be called while there are any unfinished calls to
401    * the run(), run_one(), poll() or poll_one() functions.
402    */
403   ASIO_DECL void reset();
404 
405   /// Request the io_service to invoke the given handler.
406   /**
407    * This function is used to ask the io_service to execute the given handler.
408    *
409    * The io_service guarantees that the handler will only be called in a thread
410    * in which the run(), run_one(), poll() or poll_one() member functions is
411    * currently being invoked. The handler may be executed inside this function
412    * if the guarantee can be met.
413    *
414    * @param handler The handler to be called. The io_service will make
415    * a copy of the handler object as required. The function signature of the
416    * handler must be: @code void handler(); @endcode
417    *
418    * @note This function throws an exception only if:
419    *
420    * @li the handler's @c asio_handler_allocate function; or
421    *
422    * @li the handler's copy constructor
423    *
424    * throws an exception.
425    */
426   template <typename CompletionHandler>
427   ASIO_INITFN_RESULT_TYPE(CompletionHandler, void ())
428   dispatch(ASIO_MOVE_ARG(CompletionHandler) handler);
429 
430   /// Request the io_service to invoke the given handler and return immediately.
431   /**
432    * This function is used to ask the io_service to execute the given handler,
433    * but without allowing the io_service to call the handler from inside this
434    * function.
435    *
436    * The io_service guarantees that the handler will only be called in a thread
437    * in which the run(), run_one(), poll() or poll_one() member functions is
438    * currently being invoked.
439    *
440    * @param handler The handler to be called. The io_service will make
441    * a copy of the handler object as required. The function signature of the
442    * handler must be: @code void handler(); @endcode
443    *
444    * @note This function throws an exception only if:
445    *
446    * @li the handler's @c asio_handler_allocate function; or
447    *
448    * @li the handler's copy constructor
449    *
450    * throws an exception.
451    */
452   template <typename CompletionHandler>
453   ASIO_INITFN_RESULT_TYPE(CompletionHandler, void ())
454   post(ASIO_MOVE_ARG(CompletionHandler) handler);
455 
456   /// Create a new handler that automatically dispatches the wrapped handler
457   /// on the io_service.
458   /**
459    * This function is used to create a new handler function object that, when
460    * invoked, will automatically pass the wrapped handler to the io_service
461    * object's dispatch function.
462    *
463    * @param handler The handler to be wrapped. The io_service will make a copy
464    * of the handler object as required. The function signature of the handler
465    * must be: @code void handler(A1 a1, ... An an); @endcode
466    *
467    * @return A function object that, when invoked, passes the wrapped handler to
468    * the io_service object's dispatch function. Given a function object with the
469    * signature:
470    * @code R f(A1 a1, ... An an); @endcode
471    * If this function object is passed to the wrap function like so:
472    * @code io_service.wrap(f); @endcode
473    * then the return value is a function object with the signature
474    * @code void g(A1 a1, ... An an); @endcode
475    * that, when invoked, executes code equivalent to:
476    * @code io_service.dispatch(boost::bind(f, a1, ... an)); @endcode
477    */
478   template <typename Handler>
479   detail::wrapped_handler<io_service&, Handler>
480   wrap(Handler handler);
481 
482   /// Fork-related event notifications.
483   enum fork_event
484   {
485     /// Notify the io_service that the process is about to fork.
486     fork_prepare,
487 
488     /// Notify the io_service that the process has forked and is the parent.
489     fork_parent,
490 
491     /// Notify the io_service that the process has forked and is the child.
492     fork_child
493   };
494 
495   /// Notify the io_service of a fork-related event.
496   /**
497    * This function is used to inform the io_service that the process is about
498    * to fork, or has just forked. This allows the io_service, and the services
499    * it contains, to perform any necessary housekeeping to ensure correct
500    * operation following a fork.
501    *
502    * This function must not be called while any other io_service function, or
503    * any function on an I/O object associated with the io_service, is being
504    * called in another thread. It is, however, safe to call this function from
505    * within a completion handler, provided no other thread is accessing the
506    * io_service.
507    *
508    * @param event A fork-related event.
509    *
510    * @throws asio::system_error Thrown on failure. If the notification
511    * fails the io_service object should no longer be used and should be
512    * destroyed.
513    *
514    * @par Example
515    * The following code illustrates how to incorporate the notify_fork()
516    * function:
517    * @code my_io_service.notify_fork(asio::io_service::fork_prepare);
518    * if (fork() == 0)
519    * {
520    *   // This is the child process.
521    *   my_io_service.notify_fork(asio::io_service::fork_child);
522    * }
523    * else
524    * {
525    *   // This is the parent process.
526    *   my_io_service.notify_fork(asio::io_service::fork_parent);
527    * } @endcode
528    *
529    * @note For each service object @c svc in the io_service set, performs
530    * <tt>svc->fork_service();</tt>. When processing the fork_prepare event,
531    * services are visited in reverse order of the beginning of service object
532    * lifetime. Otherwise, services are visited in order of the beginning of
533    * service object lifetime.
534    */
535   ASIO_DECL void notify_fork(asio::io_service::fork_event event);
536 
537   /// Obtain the service object corresponding to the given type.
538   /**
539    * This function is used to locate a service object that corresponds to
540    * the given service type. If there is no existing implementation of the
541    * service, then the io_service will create a new instance of the service.
542    *
543    * @param ios The io_service object that owns the service.
544    *
545    * @return The service interface implementing the specified service type.
546    * Ownership of the service interface is not transferred to the caller.
547    */
548   template <typename Service>
549   friend Service& use_service(io_service& ios);
550 
551   /// Add a service object to the io_service.
552   /**
553    * This function is used to add a service to the io_service.
554    *
555    * @param ios The io_service object that owns the service.
556    *
557    * @param svc The service object. On success, ownership of the service object
558    * is transferred to the io_service. When the io_service object is destroyed,
559    * it will destroy the service object by performing:
560    * @code delete static_cast<io_service::service*>(svc) @endcode
561    *
562    * @throws asio::service_already_exists Thrown if a service of the
563    * given type is already present in the io_service.
564    *
565    * @throws asio::invalid_service_owner Thrown if the service's owning
566    * io_service is not the io_service object specified by the ios parameter.
567    */
568   template <typename Service>
569   friend void add_service(io_service& ios, Service* svc);
570 
571   /// Determine if an io_service contains a specified service type.
572   /**
573    * This function is used to determine whether the io_service contains a
574    * service object corresponding to the given service type.
575    *
576    * @param ios The io_service object that owns the service.
577    *
578    * @return A boolean indicating whether the io_service contains the service.
579    */
580   template <typename Service>
581   friend bool has_service(io_service& ios);
582 
583 private:
584 #if   defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX)    || defined(__osf__)
585   detail::signal_init<> init_;
586 #endif
587 
588   // The service registry.
589   asio::detail::service_registry* service_registry_;
590 
591   // The implementation.
592   impl_type& impl_;
593 };
594 
595 /// Class to inform the io_service when it has work to do.
596 /**
597  * The work class is used to inform the io_service when work starts and
598  * finishes. This ensures that the io_service object's run() function will not
599  * exit while work is underway, and that it does exit when there is no
600  * unfinished work remaining.
601  *
602  * The work class is copy-constructible so that it may be used as a data member
603  * in a handler class. It is not assignable.
604  */
605 class io_service::work
606 {
607 public:
608   /// Constructor notifies the io_service that work is starting.
609   /**
610    * The constructor is used to inform the io_service that some work has begun.
611    * This ensures that the io_service object's run() function will not exit
612    * while the work is underway.
613    */
614   explicit work(asio::io_service& io_service);
615 
616   /// Copy constructor notifies the io_service that work is starting.
617   /**
618    * The constructor is used to inform the io_service that some work has begun.
619    * This ensures that the io_service object's run() function will not exit
620    * while the work is underway.
621    */
622   work(const work& other);
623 
624   /// Destructor notifies the io_service that the work is complete.
625   /**
626    * The destructor is used to inform the io_service that some work has
627    * finished. Once the count of unfinished work reaches zero, the io_service
628    * object's run() function is permitted to exit.
629    */
630   ~work();
631 
632   /// Get the io_service associated with the work.
633   asio::io_service& get_io_service();
634 
635 private:
636   // Prevent assignment.
637   void operator=(const work& other);
638 
639   // The io_service implementation.
640   detail::io_service_impl& io_service_impl_;
641 };
642 
643 /// Class used to uniquely identify a service.
644 class io_service::id
645   : private noncopyable
646 {
647 public:
648   /// Constructor.
id()649   id() {}
650 };
651 
652 /// Base class for all io_service services.
653 class io_service::service
654   : private noncopyable
655 {
656 public:
657   /// Get the io_service object that owns the service.
658   asio::io_service& get_io_service();
659 
660 protected:
661   /// Constructor.
662   /**
663    * @param owner The io_service object that owns the service.
664    */
665   ASIO_DECL service(asio::io_service& owner);
666 
667   /// Destructor.
668   ASIO_DECL virtual ~service();
669 
670 private:
671   /// Destroy all user-defined handler objects owned by the service.
672   virtual void shutdown_service() = 0;
673 
674   /// Handle notification of a fork-related event to perform any necessary
675   /// housekeeping.
676   /**
677    * This function is not a pure virtual so that services only have to
678    * implement it if necessary. The default implementation does nothing.
679    */
680   ASIO_DECL virtual void fork_service(
681       asio::io_service::fork_event event);
682 
683   friend class asio::detail::service_registry;
684   struct key
685   {
keyasio::io_service::service::key686     key() : type_info_(0), id_(0) {}
687     const std::type_info* type_info_;
688     const asio::io_service::id* id_;
689   } key_;
690 
691   asio::io_service& owner_;
692   service* next_;
693 };
694 
695 /// Exception thrown when trying to add a duplicate service to an io_service.
696 class service_already_exists
697   : public std::logic_error
698 {
699 public:
700   ASIO_DECL service_already_exists();
701 };
702 
703 /// Exception thrown when trying to add a service object to an io_service where
704 /// the service has a different owner.
705 class invalid_service_owner
706   : public std::logic_error
707 {
708 public:
709   ASIO_DECL invalid_service_owner();
710 };
711 
712 namespace detail {
713 
714 // Special derived service id type to keep classes header-file only.
715 template <typename Type>
716 class service_id
717   : public asio::io_service::id
718 {
719 };
720 
721 // Special service base class to keep classes header-file only.
722 template <typename Type>
723 class service_base
724   : public asio::io_service::service
725 {
726 public:
727   static asio::detail::service_id<Type> id;
728 
729   // Constructor.
service_base(asio::io_service & io_service)730   service_base(asio::io_service& io_service)
731     : asio::io_service::service(io_service)
732   {
733   }
734 };
735 
736 template <typename Type>
737 asio::detail::service_id<Type> service_base<Type>::id;
738 
739 } // namespace detail
740 } // namespace asio
741 
742 #include "asio/detail/pop_options.hpp"
743 
744 #include "asio/impl/io_service.hpp"
745 # include "asio/impl/io_service.ipp"
746 
747 #endif // ASIO_IO_SERVICE_HPP
748