Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:31

0001 //
0002 // detail/impl/handler_tracking.ipp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP
0012 #define BOOST_ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 
0020 #if defined(BOOST_ASIO_CUSTOM_HANDLER_TRACKING)
0021 
0022 // The handler tracking implementation is provided by the user-specified header.
0023 
0024 #elif defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
0025 
0026 #include <cstdarg>
0027 #include <cstdio>
0028 #include <boost/asio/detail/handler_tracking.hpp>
0029 
0030 #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
0031 # include <boost/asio/time_traits.hpp>
0032 #else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
0033 # include <boost/asio/detail/chrono.hpp>
0034 # include <boost/asio/detail/chrono_time_traits.hpp>
0035 # include <boost/asio/wait_traits.hpp>
0036 #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
0037 
0038 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
0039 # include <boost/asio/detail/socket_types.hpp>
0040 #elif !defined(BOOST_ASIO_WINDOWS)
0041 # include <unistd.h>
0042 #endif // !defined(BOOST_ASIO_WINDOWS)
0043 
0044 #include <boost/asio/detail/push_options.hpp>
0045 
0046 namespace boost {
0047 namespace asio {
0048 namespace detail {
0049 
0050 struct handler_tracking_timestamp
0051 {
0052   uint64_t seconds;
0053   uint64_t microseconds;
0054 
0055   handler_tracking_timestamp()
0056   {
0057 #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
0058     boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
0059     boost::posix_time::time_duration now =
0060       boost::posix_time::microsec_clock::universal_time() - epoch;
0061 #else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
0062     typedef chrono_time_traits<chrono::system_clock,
0063         boost::asio::wait_traits<chrono::system_clock>> traits_helper;
0064     traits_helper::posix_time_duration now(
0065         chrono::system_clock::now().time_since_epoch());
0066 #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
0067     seconds = static_cast<uint64_t>(now.total_seconds());
0068     microseconds = static_cast<uint64_t>(now.total_microseconds() % 1000000);
0069   }
0070 };
0071 
0072 struct handler_tracking::tracking_state
0073 {
0074   static_mutex mutex_;
0075   uint64_t next_id_;
0076   tss_ptr<completion>* current_completion_;
0077   tss_ptr<location>* current_location_;
0078 };
0079 
0080 handler_tracking::tracking_state* handler_tracking::get_state()
0081 {
0082   static tracking_state state = { BOOST_ASIO_STATIC_MUTEX_INIT, 1, 0, 0 };
0083   return &state;
0084 }
0085 
0086 void handler_tracking::init()
0087 {
0088   static tracking_state* state = get_state();
0089 
0090   state->mutex_.init();
0091 
0092   static_mutex::scoped_lock lock(state->mutex_);
0093   if (state->current_completion_ == 0)
0094     state->current_completion_ = new tss_ptr<completion>;
0095   if (state->current_location_ == 0)
0096     state->current_location_ = new tss_ptr<location>;
0097 }
0098 
0099 handler_tracking::location::location(
0100     const char* file, int line, const char* func)
0101   : file_(file),
0102     line_(line),
0103     func_(func),
0104     next_(*get_state()->current_location_)
0105 {
0106   if (file_)
0107     *get_state()->current_location_ = this;
0108 }
0109 
0110 handler_tracking::location::~location()
0111 {
0112   if (file_)
0113     *get_state()->current_location_ = next_;
0114 }
0115 
0116 void handler_tracking::creation(execution_context&,
0117     handler_tracking::tracked_handler& h,
0118     const char* object_type, void* object,
0119     uintmax_t /*native_handle*/, const char* op_name)
0120 {
0121   static tracking_state* state = get_state();
0122 
0123   static_mutex::scoped_lock lock(state->mutex_);
0124   h.id_ = state->next_id_++;
0125   lock.unlock();
0126 
0127   handler_tracking_timestamp timestamp;
0128 
0129   uint64_t current_id = 0;
0130   if (completion* current_completion = *state->current_completion_)
0131     current_id = current_completion->id_;
0132 
0133   for (location* current_location = *state->current_location_;
0134       current_location; current_location = current_location->next_)
0135   {
0136     write_line(
0137 #if defined(BOOST_ASIO_WINDOWS)
0138         "@asio|%I64u.%06I64u|%I64u^%I64u|%s%s%.80s%s(%.80s:%d)\n",
0139 #else // defined(BOOST_ASIO_WINDOWS)
0140         "@asio|%llu.%06llu|%llu^%llu|%s%s%.80s%s(%.80s:%d)\n",
0141 #endif // defined(BOOST_ASIO_WINDOWS)
0142         timestamp.seconds, timestamp.microseconds,
0143         current_id, h.id_,
0144         current_location == *state->current_location_ ? "in " : "called from ",
0145         current_location->func_ ? "'" : "",
0146         current_location->func_ ? current_location->func_ : "",
0147         current_location->func_ ? "' " : "",
0148         current_location->file_, current_location->line_);
0149   }
0150 
0151   write_line(
0152 #if defined(BOOST_ASIO_WINDOWS)
0153       "@asio|%I64u.%06I64u|%I64u*%I64u|%.20s@%p.%.50s\n",
0154 #else // defined(BOOST_ASIO_WINDOWS)
0155       "@asio|%llu.%06llu|%llu*%llu|%.20s@%p.%.50s\n",
0156 #endif // defined(BOOST_ASIO_WINDOWS)
0157       timestamp.seconds, timestamp.microseconds,
0158       current_id, h.id_, object_type, object, op_name);
0159 }
0160 
0161 handler_tracking::completion::completion(
0162     const handler_tracking::tracked_handler& h)
0163   : id_(h.id_),
0164     invoked_(false),
0165     next_(*get_state()->current_completion_)
0166 {
0167   *get_state()->current_completion_ = this;
0168 }
0169 
0170 handler_tracking::completion::~completion()
0171 {
0172   if (id_)
0173   {
0174     handler_tracking_timestamp timestamp;
0175 
0176     write_line(
0177 #if defined(BOOST_ASIO_WINDOWS)
0178         "@asio|%I64u.%06I64u|%c%I64u|\n",
0179 #else // defined(BOOST_ASIO_WINDOWS)
0180         "@asio|%llu.%06llu|%c%llu|\n",
0181 #endif // defined(BOOST_ASIO_WINDOWS)
0182         timestamp.seconds, timestamp.microseconds,
0183         invoked_ ? '!' : '~', id_);
0184   }
0185 
0186   *get_state()->current_completion_ = next_;
0187 }
0188 
0189 void handler_tracking::completion::invocation_begin()
0190 {
0191   handler_tracking_timestamp timestamp;
0192 
0193   write_line(
0194 #if defined(BOOST_ASIO_WINDOWS)
0195       "@asio|%I64u.%06I64u|>%I64u|\n",
0196 #else // defined(BOOST_ASIO_WINDOWS)
0197       "@asio|%llu.%06llu|>%llu|\n",
0198 #endif // defined(BOOST_ASIO_WINDOWS)
0199       timestamp.seconds, timestamp.microseconds, id_);
0200 
0201   invoked_ = true;
0202 }
0203 
0204 void handler_tracking::completion::invocation_begin(
0205     const boost::system::error_code& ec)
0206 {
0207   handler_tracking_timestamp timestamp;
0208 
0209   write_line(
0210 #if defined(BOOST_ASIO_WINDOWS)
0211       "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d\n",
0212 #else // defined(BOOST_ASIO_WINDOWS)
0213       "@asio|%llu.%06llu|>%llu|ec=%.20s:%d\n",
0214 #endif // defined(BOOST_ASIO_WINDOWS)
0215       timestamp.seconds, timestamp.microseconds,
0216       id_, ec.category().name(), ec.value());
0217 
0218   invoked_ = true;
0219 }
0220 
0221 void handler_tracking::completion::invocation_begin(
0222     const boost::system::error_code& ec, std::size_t bytes_transferred)
0223 {
0224   handler_tracking_timestamp timestamp;
0225 
0226   write_line(
0227 #if defined(BOOST_ASIO_WINDOWS)
0228       "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,bytes_transferred=%I64u\n",
0229 #else // defined(BOOST_ASIO_WINDOWS)
0230       "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,bytes_transferred=%llu\n",
0231 #endif // defined(BOOST_ASIO_WINDOWS)
0232       timestamp.seconds, timestamp.microseconds,
0233       id_, ec.category().name(), ec.value(),
0234       static_cast<uint64_t>(bytes_transferred));
0235 
0236   invoked_ = true;
0237 }
0238 
0239 void handler_tracking::completion::invocation_begin(
0240     const boost::system::error_code& ec, int signal_number)
0241 {
0242   handler_tracking_timestamp timestamp;
0243 
0244   write_line(
0245 #if defined(BOOST_ASIO_WINDOWS)
0246       "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,signal_number=%d\n",
0247 #else // defined(BOOST_ASIO_WINDOWS)
0248       "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,signal_number=%d\n",
0249 #endif // defined(BOOST_ASIO_WINDOWS)
0250       timestamp.seconds, timestamp.microseconds,
0251       id_, ec.category().name(), ec.value(), signal_number);
0252 
0253   invoked_ = true;
0254 }
0255 
0256 void handler_tracking::completion::invocation_begin(
0257     const boost::system::error_code& ec, const char* arg)
0258 {
0259   handler_tracking_timestamp timestamp;
0260 
0261   write_line(
0262 #if defined(BOOST_ASIO_WINDOWS)
0263       "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,%.50s\n",
0264 #else // defined(BOOST_ASIO_WINDOWS)
0265       "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,%.50s\n",
0266 #endif // defined(BOOST_ASIO_WINDOWS)
0267       timestamp.seconds, timestamp.microseconds,
0268       id_, ec.category().name(), ec.value(), arg);
0269 
0270   invoked_ = true;
0271 }
0272 
0273 void handler_tracking::completion::invocation_end()
0274 {
0275   if (id_)
0276   {
0277     handler_tracking_timestamp timestamp;
0278 
0279     write_line(
0280 #if defined(BOOST_ASIO_WINDOWS)
0281         "@asio|%I64u.%06I64u|<%I64u|\n",
0282 #else // defined(BOOST_ASIO_WINDOWS)
0283         "@asio|%llu.%06llu|<%llu|\n",
0284 #endif // defined(BOOST_ASIO_WINDOWS)
0285         timestamp.seconds, timestamp.microseconds, id_);
0286 
0287     id_ = 0;
0288   }
0289 }
0290 
0291 void handler_tracking::operation(execution_context&,
0292     const char* object_type, void* object,
0293     uintmax_t /*native_handle*/, const char* op_name)
0294 {
0295   static tracking_state* state = get_state();
0296 
0297   handler_tracking_timestamp timestamp;
0298 
0299   unsigned long long current_id = 0;
0300   if (completion* current_completion = *state->current_completion_)
0301     current_id = current_completion->id_;
0302 
0303   write_line(
0304 #if defined(BOOST_ASIO_WINDOWS)
0305       "@asio|%I64u.%06I64u|%I64u|%.20s@%p.%.50s\n",
0306 #else // defined(BOOST_ASIO_WINDOWS)
0307       "@asio|%llu.%06llu|%llu|%.20s@%p.%.50s\n",
0308 #endif // defined(BOOST_ASIO_WINDOWS)
0309       timestamp.seconds, timestamp.microseconds,
0310       current_id, object_type, object, op_name);
0311 }
0312 
0313 void handler_tracking::reactor_registration(execution_context& /*context*/,
0314     uintmax_t /*native_handle*/, uintmax_t /*registration*/)
0315 {
0316 }
0317 
0318 void handler_tracking::reactor_deregistration(execution_context& /*context*/,
0319     uintmax_t /*native_handle*/, uintmax_t /*registration*/)
0320 {
0321 }
0322 
0323 void handler_tracking::reactor_events(execution_context& /*context*/,
0324     uintmax_t /*native_handle*/, unsigned /*events*/)
0325 {
0326 }
0327 
0328 void handler_tracking::reactor_operation(
0329     const tracked_handler& h, const char* op_name,
0330     const boost::system::error_code& ec)
0331 {
0332   handler_tracking_timestamp timestamp;
0333 
0334   write_line(
0335 #if defined(BOOST_ASIO_WINDOWS)
0336       "@asio|%I64u.%06I64u|.%I64u|%s,ec=%.20s:%d\n",
0337 #else // defined(BOOST_ASIO_WINDOWS)
0338       "@asio|%llu.%06llu|.%llu|%s,ec=%.20s:%d\n",
0339 #endif // defined(BOOST_ASIO_WINDOWS)
0340       timestamp.seconds, timestamp.microseconds,
0341       h.id_, op_name, ec.category().name(), ec.value());
0342 }
0343 
0344 void handler_tracking::reactor_operation(
0345     const tracked_handler& h, const char* op_name,
0346     const boost::system::error_code& ec, std::size_t bytes_transferred)
0347 {
0348   handler_tracking_timestamp timestamp;
0349 
0350   write_line(
0351 #if defined(BOOST_ASIO_WINDOWS)
0352       "@asio|%I64u.%06I64u|.%I64u|%s,ec=%.20s:%d,bytes_transferred=%I64u\n",
0353 #else // defined(BOOST_ASIO_WINDOWS)
0354       "@asio|%llu.%06llu|.%llu|%s,ec=%.20s:%d,bytes_transferred=%llu\n",
0355 #endif // defined(BOOST_ASIO_WINDOWS)
0356       timestamp.seconds, timestamp.microseconds,
0357       h.id_, op_name, ec.category().name(), ec.value(),
0358       static_cast<uint64_t>(bytes_transferred));
0359 }
0360 
0361 void handler_tracking::write_line(const char* format, ...)
0362 {
0363   using namespace std; // For sprintf (or equivalent).
0364 
0365   va_list args;
0366   va_start(args, format);
0367 
0368   char line[256] = "";
0369 #if defined(BOOST_ASIO_HAS_SNPRINTF)
0370   int length = vsnprintf(line, sizeof(line), format, args);
0371 #elif defined(BOOST_ASIO_HAS_SECURE_RTL)
0372   int length = vsprintf_s(line, sizeof(line), format, args);
0373 #else // defined(BOOST_ASIO_HAS_SECURE_RTL)
0374   int length = vsprintf(line, format, args);
0375 #endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
0376 
0377   va_end(args);
0378 
0379 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
0380   wchar_t wline[256] = L"";
0381   mbstowcs_s(0, wline, sizeof(wline) / sizeof(wchar_t), line, length);
0382   ::OutputDebugStringW(wline);
0383 #elif defined(BOOST_ASIO_WINDOWS)
0384   HANDLE stderr_handle = ::GetStdHandle(STD_ERROR_HANDLE);
0385   DWORD bytes_written = 0;
0386   ::WriteFile(stderr_handle, line, length, &bytes_written, 0);
0387 #else // defined(BOOST_ASIO_WINDOWS)
0388   ::write(STDERR_FILENO, line, length);
0389 #endif // defined(BOOST_ASIO_WINDOWS)
0390 }
0391 
0392 } // namespace detail
0393 } // namespace asio
0394 } // namespace boost
0395 
0396 #include <boost/asio/detail/pop_options.hpp>
0397 
0398 #endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
0399 
0400 #endif // BOOST_ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP