1 // 2 // detail/win_object_handle_service.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) 7 // 8 // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 // 11 12 #ifndef BOOST_ASIO_DETAIL_WIN_OBJECT_HANDLE_SERVICE_HPP 13 #define BOOST_ASIO_DETAIL_WIN_OBJECT_HANDLE_SERVICE_HPP 14 15 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 # pragma once 17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 19 #include <boost/asio/detail/config.hpp> 20 21 #if defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) 22 23 #include <boost/asio/detail/addressof.hpp> 24 #include <boost/asio/detail/handler_alloc_helpers.hpp> 25 #include <boost/asio/detail/wait_handler.hpp> 26 #include <boost/asio/error.hpp> 27 #include <boost/asio/io_service.hpp> 28 29 #include <boost/asio/detail/push_options.hpp> 30 31 namespace boost { 32 namespace asio { 33 namespace detail { 34 35 class win_object_handle_service 36 { 37 public: 38 // The native type of an object handle. 39 typedef HANDLE native_handle_type; 40 41 // The implementation type of the object handle. 42 class implementation_type 43 { 44 public: 45 // Default constructor. implementation_type()46 implementation_type() 47 : handle_(INVALID_HANDLE_VALUE), 48 wait_handle_(INVALID_HANDLE_VALUE), 49 owner_(0), 50 next_(0), 51 prev_(0) 52 { 53 } 54 55 private: 56 // Only this service will have access to the internal values. 57 friend class win_object_handle_service; 58 59 // The native object handle representation. May be accessed or modified 60 // without locking the mutex. 61 native_handle_type handle_; 62 63 // The handle used to unregister the wait operation. The mutex must be 64 // locked when accessing or modifying this member. 65 HANDLE wait_handle_; 66 67 // The operations waiting on the object handle. If there is a registered 68 // wait then the mutex must be locked when accessing or modifying this 69 // member 70 op_queue<wait_op> op_queue_; 71 72 // The service instance that owns the object handle implementation. 73 win_object_handle_service* owner_; 74 75 // Pointers to adjacent handle implementations in linked list. The mutex 76 // must be locked when accessing or modifying these members. 77 implementation_type* next_; 78 implementation_type* prev_; 79 }; 80 81 // Constructor. 82 BOOST_ASIO_DECL win_object_handle_service( 83 boost::asio::io_service& io_service); 84 85 // Destroy all user-defined handler objects owned by the service. 86 BOOST_ASIO_DECL void shutdown_service(); 87 88 // Construct a new handle implementation. 89 BOOST_ASIO_DECL void construct(implementation_type& impl); 90 91 // Move-construct a new handle implementation. 92 BOOST_ASIO_DECL void move_construct(implementation_type& impl, 93 implementation_type& other_impl); 94 95 // Move-assign from another handle implementation. 96 BOOST_ASIO_DECL void move_assign(implementation_type& impl, 97 win_object_handle_service& other_service, 98 implementation_type& other_impl); 99 100 // Destroy a handle implementation. 101 BOOST_ASIO_DECL void destroy(implementation_type& impl); 102 103 // Assign a native handle to a handle implementation. 104 BOOST_ASIO_DECL boost::system::error_code assign(implementation_type& impl, 105 const native_handle_type& handle, boost::system::error_code& ec); 106 107 // Determine whether the handle is open. is_open(const implementation_type & impl) const108 bool is_open(const implementation_type& impl) const 109 { 110 return impl.handle_ != INVALID_HANDLE_VALUE && impl.handle_ != 0; 111 } 112 113 // Destroy a handle implementation. 114 BOOST_ASIO_DECL boost::system::error_code close(implementation_type& impl, 115 boost::system::error_code& ec); 116 117 // Get the native handle representation. native_handle(const implementation_type & impl) const118 native_handle_type native_handle(const implementation_type& impl) const 119 { 120 return impl.handle_; 121 } 122 123 // Cancel all operations associated with the handle. 124 BOOST_ASIO_DECL boost::system::error_code cancel(implementation_type& impl, 125 boost::system::error_code& ec); 126 127 // Perform a synchronous wait for the object to enter a signalled state. 128 BOOST_ASIO_DECL void wait(implementation_type& impl, 129 boost::system::error_code& ec); 130 131 /// Start an asynchronous wait. 132 template <typename Handler> async_wait(implementation_type & impl,Handler & handler)133 void async_wait(implementation_type& impl, Handler& handler) 134 { 135 // Allocate and construct an operation to wrap the handler. 136 typedef wait_handler<Handler> op; 137 typename op::ptr p = { boost::asio::detail::addressof(handler), 138 boost_asio_handler_alloc_helpers::allocate( 139 sizeof(op), handler), 0 }; 140 p.p = new (p.v) op(handler); 141 142 BOOST_ASIO_HANDLER_CREATION((p.p, "object_handle", &impl, "async_wait")); 143 144 start_wait_op(impl, p.p); 145 p.v = p.p = 0; 146 } 147 148 private: 149 // Helper function to start an asynchronous wait operation. 150 BOOST_ASIO_DECL void start_wait_op(implementation_type& impl, wait_op* op); 151 152 // Helper function to register a wait operation. 153 BOOST_ASIO_DECL void register_wait_callback( 154 implementation_type& impl, mutex::scoped_lock& lock); 155 156 // Callback function invoked when the registered wait completes. 157 static BOOST_ASIO_DECL VOID CALLBACK wait_callback( 158 PVOID param, BOOLEAN timeout); 159 160 // The io_service implementation used to post completions. 161 io_service_impl& io_service_; 162 163 // Mutex to protect access to internal state. 164 mutex mutex_; 165 166 // The head of a linked list of all implementations. 167 implementation_type* impl_list_; 168 169 // Flag to indicate that the dispatcher has been shut down. 170 bool shutdown_; 171 }; 172 173 } // namespace detail 174 } // namespace asio 175 } // namespace boost 176 177 #include <boost/asio/detail/pop_options.hpp> 178 179 #if defined(BOOST_ASIO_HEADER_ONLY) 180 # include <boost/asio/detail/impl/win_object_handle_service.ipp> 181 #endif // defined(BOOST_ASIO_HEADER_ONLY) 182 183 #endif // defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) 184 185 #endif // BOOST_ASIO_DETAIL_WIN_OBJECT_HANDLE_SERVICE_HPP 186