1 // 2 // detail/handler_tracking.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2021 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 BOOST_ASIO_DETAIL_HANDLER_TRACKING_HPP 12 #define BOOST_ASIO_DETAIL_HANDLER_TRACKING_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 20 namespace boost { 21 namespace asio { 22 23 class execution_context; 24 25 } // namespace asio 26 } // namespace boost 27 28 #if defined(BOOST_ASIO_CUSTOM_HANDLER_TRACKING) 29 # include BOOST_ASIO_CUSTOM_HANDLER_TRACKING 30 #elif defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING) 31 # include <boost/system/error_code.hpp> 32 # include <boost/asio/detail/cstdint.hpp> 33 # include <boost/asio/detail/static_mutex.hpp> 34 # include <boost/asio/detail/tss_ptr.hpp> 35 #endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING) 36 37 #include <boost/asio/detail/push_options.hpp> 38 39 namespace boost { 40 namespace asio { 41 namespace detail { 42 43 #if defined(BOOST_ASIO_CUSTOM_HANDLER_TRACKING) 44 45 // The user-specified header must define the following macros: 46 // - BOOST_ASIO_INHERIT_TRACKED_HANDLER 47 // - BOOST_ASIO_ALSO_INHERIT_TRACKED_HANDLER 48 // - BOOST_ASIO_HANDLER_TRACKING_INIT 49 // - BOOST_ASIO_HANDLER_CREATION(args) 50 // - BOOST_ASIO_HANDLER_COMPLETION(args) 51 // - BOOST_ASIO_HANDLER_INVOCATION_BEGIN(args) 52 // - BOOST_ASIO_HANDLER_INVOCATION_END 53 // - BOOST_ASIO_HANDLER_OPERATION(args) 54 // - BOOST_ASIO_HANDLER_REACTOR_REGISTRATION(args) 55 // - BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION(args) 56 // - BOOST_ASIO_HANDLER_REACTOR_READ_EVENT 57 // - BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT 58 // - BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT 59 // - BOOST_ASIO_HANDLER_REACTOR_EVENTS(args) 60 // - BOOST_ASIO_HANDLER_REACTOR_OPERATION(args) 61 62 # if !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING) 63 # define BOOST_ASIO_ENABLE_HANDLER_TRACKING 1 64 # endif /// !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING) 65 66 #elif defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING) 67 68 class handler_tracking 69 { 70 public: 71 class completion; 72 73 // Base class for objects containing tracked handlers. 74 class tracked_handler 75 { 76 private: 77 // Only the handler_tracking class will have access to the id. 78 friend class handler_tracking; 79 friend class completion; 80 uint64_t id_; 81 82 protected: 83 // Constructor initialises with no id. 84 tracked_handler() : id_(0) {} 85 86 // Prevent deletion through this type. 87 ~tracked_handler() {} 88 }; 89 90 // Initialise the tracking system. 91 BOOST_ASIO_DECL static void init(); 92 93 class location 94 { 95 public: 96 // Constructor adds a location to the stack. 97 BOOST_ASIO_DECL explicit location(const char* file, 98 int line, const char* func); 99 100 // Destructor removes a location from the stack. 101 BOOST_ASIO_DECL ~location(); 102 103 private: 104 // Disallow copying and assignment. 105 location(const location&) BOOST_ASIO_DELETED; 106 location& operator=(const location&) BOOST_ASIO_DELETED; 107 108 friend class handler_tracking; 109 const char* file_; 110 int line_; 111 const char* func_; 112 location* next_; 113 }; 114 115 // Record the creation of a tracked handler. 116 BOOST_ASIO_DECL static void creation( 117 execution_context& context, tracked_handler& h, 118 const char* object_type, void* object, 119 uintmax_t native_handle, const char* op_name); 120 121 class completion 122 { 123 public: 124 // Constructor records that handler is to be invoked with no arguments. 125 BOOST_ASIO_DECL explicit completion(const tracked_handler& h); 126 127 // Destructor records only when an exception is thrown from the handler, or 128 // if the memory is being freed without the handler having been invoked. 129 BOOST_ASIO_DECL ~completion(); 130 131 // Records that handler is to be invoked with no arguments. 132 BOOST_ASIO_DECL void invocation_begin(); 133 134 // Records that handler is to be invoked with one arguments. 135 BOOST_ASIO_DECL void invocation_begin(const boost::system::error_code& ec); 136 137 // Constructor records that handler is to be invoked with two arguments. 138 BOOST_ASIO_DECL void invocation_begin( 139 const boost::system::error_code& ec, std::size_t bytes_transferred); 140 141 // Constructor records that handler is to be invoked with two arguments. 142 BOOST_ASIO_DECL void invocation_begin( 143 const boost::system::error_code& ec, int signal_number); 144 145 // Constructor records that handler is to be invoked with two arguments. 146 BOOST_ASIO_DECL void invocation_begin( 147 const boost::system::error_code& ec, const char* arg); 148 149 // Record that handler invocation has ended. 150 BOOST_ASIO_DECL void invocation_end(); 151 152 private: 153 friend class handler_tracking; 154 uint64_t id_; 155 bool invoked_; 156 completion* next_; 157 }; 158 159 // Record an operation that is not directly associated with a handler. 160 BOOST_ASIO_DECL static void operation(execution_context& context, 161 const char* object_type, void* object, 162 uintmax_t native_handle, const char* op_name); 163 164 // Record that a descriptor has been registered with the reactor. 165 BOOST_ASIO_DECL static void reactor_registration(execution_context& context, 166 uintmax_t native_handle, uintmax_t registration); 167 168 // Record that a descriptor has been deregistered from the reactor. 169 BOOST_ASIO_DECL static void reactor_deregistration(execution_context& context, 170 uintmax_t native_handle, uintmax_t registration); 171 172 // Record a reactor-based operation that is associated with a handler. 173 BOOST_ASIO_DECL static void reactor_events(execution_context& context, 174 uintmax_t registration, unsigned events); 175 176 // Record a reactor-based operation that is associated with a handler. 177 BOOST_ASIO_DECL static void reactor_operation( 178 const tracked_handler& h, const char* op_name, 179 const boost::system::error_code& ec); 180 181 // Record a reactor-based operation that is associated with a handler. 182 BOOST_ASIO_DECL static void reactor_operation( 183 const tracked_handler& h, const char* op_name, 184 const boost::system::error_code& ec, std::size_t bytes_transferred); 185 186 // Write a line of output. 187 BOOST_ASIO_DECL static void write_line(const char* format, ...); 188 189 private: 190 struct tracking_state; 191 BOOST_ASIO_DECL static tracking_state* get_state(); 192 }; 193 194 # define BOOST_ASIO_INHERIT_TRACKED_HANDLER \ 195 : public boost::asio::detail::handler_tracking::tracked_handler 196 197 # define BOOST_ASIO_ALSO_INHERIT_TRACKED_HANDLER \ 198 , public boost::asio::detail::handler_tracking::tracked_handler 199 200 # define BOOST_ASIO_HANDLER_TRACKING_INIT \ 201 boost::asio::detail::handler_tracking::init() 202 203 # define BOOST_ASIO_HANDLER_LOCATION(args) \ 204 boost::asio::detail::handler_tracking::location tracked_location args 205 206 # define BOOST_ASIO_HANDLER_CREATION(args) \ 207 boost::asio::detail::handler_tracking::creation args 208 209 # define BOOST_ASIO_HANDLER_COMPLETION(args) \ 210 boost::asio::detail::handler_tracking::completion tracked_completion args 211 212 # define BOOST_ASIO_HANDLER_INVOCATION_BEGIN(args) \ 213 tracked_completion.invocation_begin args 214 215 # define BOOST_ASIO_HANDLER_INVOCATION_END \ 216 tracked_completion.invocation_end() 217 218 # define BOOST_ASIO_HANDLER_OPERATION(args) \ 219 boost::asio::detail::handler_tracking::operation args 220 221 # define BOOST_ASIO_HANDLER_REACTOR_REGISTRATION(args) \ 222 boost::asio::detail::handler_tracking::reactor_registration args 223 224 # define BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION(args) \ 225 boost::asio::detail::handler_tracking::reactor_deregistration args 226 227 # define BOOST_ASIO_HANDLER_REACTOR_READ_EVENT 1 228 # define BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT 2 229 # define BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT 4 230 231 # define BOOST_ASIO_HANDLER_REACTOR_EVENTS(args) \ 232 boost::asio::detail::handler_tracking::reactor_events args 233 234 # define BOOST_ASIO_HANDLER_REACTOR_OPERATION(args) \ 235 boost::asio::detail::handler_tracking::reactor_operation args 236 237 #else // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING) 238 239 # define BOOST_ASIO_INHERIT_TRACKED_HANDLER 240 # define BOOST_ASIO_ALSO_INHERIT_TRACKED_HANDLER 241 # define BOOST_ASIO_HANDLER_TRACKING_INIT (void)0 242 # define BOOST_ASIO_HANDLER_LOCATION(loc) (void)0 243 # define BOOST_ASIO_HANDLER_CREATION(args) (void)0 244 # define BOOST_ASIO_HANDLER_COMPLETION(args) (void)0 245 # define BOOST_ASIO_HANDLER_INVOCATION_BEGIN(args) (void)0 246 # define BOOST_ASIO_HANDLER_INVOCATION_END (void)0 247 # define BOOST_ASIO_HANDLER_OPERATION(args) (void)0 248 # define BOOST_ASIO_HANDLER_REACTOR_REGISTRATION(args) (void)0 249 # define BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION(args) (void)0 250 # define BOOST_ASIO_HANDLER_REACTOR_READ_EVENT 0 251 # define BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT 0 252 # define BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT 0 253 # define BOOST_ASIO_HANDLER_REACTOR_EVENTS(args) (void)0 254 # define BOOST_ASIO_HANDLER_REACTOR_OPERATION(args) (void)0 255 256 #endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING) 257 258 } // namespace detail 259 } // namespace asio 260 } // namespace boost 261 262 #include <boost/asio/detail/pop_options.hpp> 263 264 #if defined(BOOST_ASIO_HEADER_ONLY) 265 # include <boost/asio/detail/impl/handler_tracking.ipp> 266 #endif // defined(BOOST_ASIO_HEADER_ONLY) 267 268 #endif // BOOST_ASIO_DETAIL_HANDLER_TRACKING_HPP 269