00001 // 00002 // io_service.hpp 00003 // ~~~~~~~~~~~~~~ 00004 // 00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) 00006 // 00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 00009 // 00010 00011 #ifndef ASIO_IO_SERVICE_HPP 00012 #define ASIO_IO_SERVICE_HPP 00013 00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 00015 # pragma once 00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 00017 00018 #include "asio/detail/push_options.hpp" 00019 00020 #include "asio/detail/push_options.hpp" 00021 #include <cstddef> 00022 #include <stdexcept> 00023 #include <typeinfo> 00024 #include <boost/config.hpp> 00025 #include <boost/throw_exception.hpp> 00026 #include "asio/detail/pop_options.hpp" 00027 00028 #include "asio/error_code.hpp" 00029 #include "asio/detail/dev_poll_reactor_fwd.hpp" 00030 #include "asio/detail/epoll_reactor_fwd.hpp" 00031 #include "asio/detail/kqueue_reactor_fwd.hpp" 00032 #include "asio/detail/noncopyable.hpp" 00033 #include "asio/detail/select_reactor_fwd.hpp" 00034 #include "asio/detail/service_registry_fwd.hpp" 00035 #include "asio/detail/signal_init.hpp" 00036 #include "asio/detail/task_io_service_fwd.hpp" 00037 #include "asio/detail/win_iocp_io_service_fwd.hpp" 00038 #include "asio/detail/winsock_init.hpp" 00039 #include "asio/detail/wrapped_handler.hpp" 00040 00041 namespace asio { 00042 00043 class io_service; 00044 template <typename Service> Service& use_service(io_service& ios); 00045 template <typename Service> void add_service(io_service& ios, Service* svc); 00046 template <typename Service> bool has_service(io_service& ios); 00047 00049 00130 class io_service 00131 : private noncopyable 00132 { 00133 private: 00134 // The type of the platform-specific implementation. 00135 #if defined(ASIO_HAS_IOCP) 00136 typedef detail::win_iocp_io_service impl_type; 00137 #elif defined(ASIO_HAS_EPOLL) 00138 typedef detail::task_io_service<detail::epoll_reactor<false> > impl_type; 00139 #elif defined(ASIO_HAS_KQUEUE) 00140 typedef detail::task_io_service<detail::kqueue_reactor<false> > impl_type; 00141 #elif defined(ASIO_HAS_DEV_POLL) 00142 typedef detail::task_io_service<detail::dev_poll_reactor<false> > impl_type; 00143 #else 00144 typedef detail::task_io_service<detail::select_reactor<false> > impl_type; 00145 #endif 00146 00147 public: 00148 class work; 00149 friend class work; 00150 00151 class id; 00152 00153 class service; 00154 00155 class strand; 00156 00158 io_service(); 00159 00161 00167 explicit io_service(std::size_t concurrency_hint); 00168 00170 ~io_service(); 00171 00173 00192 std::size_t run(); 00193 00195 00214 std::size_t run(asio::error_code& ec); 00215 00217 00225 std::size_t run_one(); 00226 00228 00236 std::size_t run_one(asio::error_code& ec); 00237 00239 00247 std::size_t poll(); 00248 00250 00258 std::size_t poll(asio::error_code& ec); 00259 00261 00269 std::size_t poll_one(); 00270 00272 00280 std::size_t poll_one(asio::error_code& ec); 00281 00283 00289 void stop(); 00290 00292 00302 void reset(); 00303 00305 00317 template <typename CompletionHandler> 00318 void dispatch(CompletionHandler handler); 00319 00321 00334 template <typename CompletionHandler> 00335 void post(CompletionHandler handler); 00336 00339 00359 template <typename Handler> 00360 #if defined(GENERATING_DOCUMENTATION) 00361 unspecified 00362 #else 00363 detail::wrapped_handler<io_service&, Handler> 00364 #endif 00365 wrap(Handler handler); 00366 00368 00378 template <typename Service> 00379 friend Service& use_service(io_service& ios); 00380 00382 00398 template <typename Service> 00399 friend void add_service(io_service& ios, Service* svc); 00400 00402 00410 template <typename Service> 00411 friend bool has_service(io_service& ios); 00412 00413 private: 00414 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) 00415 detail::winsock_init<> init_; 00416 #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ 00417 || defined(__osf__) 00418 detail::signal_init<> init_; 00419 #endif 00420 00421 // The service registry. 00422 asio::detail::service_registry* service_registry_; 00423 00424 // The implementation. 00425 impl_type& impl_; 00426 }; 00427 00429 00438 class io_service::work 00439 { 00440 public: 00442 00447 explicit work(asio::io_service& io_service); 00448 00450 00455 work(const work& other); 00456 00458 00463 ~work(); 00464 00467 asio::io_service& io_service(); 00468 00470 asio::io_service& get_io_service(); 00471 00472 private: 00473 // Prevent assignment. 00474 void operator=(const work& other); 00475 00476 // The io_service. 00477 asio::io_service& io_service_; 00478 }; 00479 00481 class io_service::id 00482 : private noncopyable 00483 { 00484 public: 00486 id() {} 00487 }; 00488 00490 class io_service::service 00491 : private noncopyable 00492 { 00493 public: 00496 asio::io_service& io_service(); 00497 00499 asio::io_service& get_io_service(); 00500 00501 protected: 00503 00506 service(asio::io_service& owner); 00507 00509 virtual ~service(); 00510 00511 private: 00513 virtual void shutdown_service() = 0; 00514 00515 friend class asio::detail::service_registry; 00516 asio::io_service& owner_; 00517 const std::type_info* type_info_; 00518 const asio::io_service::id* id_; 00519 service* next_; 00520 }; 00521 00523 class service_already_exists 00524 : public std::logic_error 00525 { 00526 public: 00527 service_already_exists() 00528 : std::logic_error("Service already exists.") 00529 { 00530 } 00531 }; 00532 00535 class invalid_service_owner 00536 : public std::logic_error 00537 { 00538 public: 00539 invalid_service_owner() 00540 : std::logic_error("Invalid service owner.") 00541 { 00542 } 00543 }; 00544 00545 } // namespace asio 00546 00547 #include "asio/impl/io_service.ipp" 00548 00549 #include "asio/detail/pop_options.hpp" 00550 00551 #endif // ASIO_IO_SERVICE_HPP