10ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 20ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// detail/impl/handler_tracking.ipp 30ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 40ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 50ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 60ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 70ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Distributed under the Boost Software License, Version 1.0. (See accompanying 80ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 90ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#ifndef ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP 120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#define ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP 130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/config.hpp" 160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#if defined(ASIO_ENABLE_HANDLER_TRACKING) 180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include <cstdarg> 200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include <cstdio> 210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/handler_tracking.hpp" 220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie# include <chrono> 240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie# include "asio/detail/chrono_time_traits.hpp" 250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie# include "asio/wait_traits.hpp" 260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie# include <unistd.h> 280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/push_options.hpp" 300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace asio { 320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace detail { 330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiestruct handler_tracking_timestamp 350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie uint64_t seconds; 370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie uint64_t microseconds; 380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp() 400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef chrono_time_traits<std::chrono::system_clock, 420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::wait_traits<std::chrono::system_clock> > traits_helper; 430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie traits_helper::posix_time_duration now( 440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie std::chrono::system_clock::now().time_since_epoch()); 450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie seconds = static_cast<uint64_t>(now.total_seconds()); 460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie microseconds = static_cast<uint64_t>(now.total_microseconds() % 1000000); 470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie}; 490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiestruct handler_tracking::tracking_state 510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static_mutex mutex_; 530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie uint64_t next_id_; 540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie tss_ptr<completion>* current_completion_; 550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie}; 560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiehandler_tracking::tracking_state* handler_tracking::get_state() 580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static tracking_state state = { ASIO_STATIC_MUTEX_INIT, 1, 0 }; 600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return &state; 610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::init() 640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static tracking_state* state = get_state(); 660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie state->mutex_.init(); 680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static_mutex::scoped_lock lock(state->mutex_); 700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (state->current_completion_ == 0) 710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie state->current_completion_ = new tss_ptr<completion>; 720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::creation(handler_tracking::tracked_handler* h, 750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const char* object_type, void* object, const char* op_name) 760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static tracking_state* state = get_state(); 780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static_mutex::scoped_lock lock(state->mutex_); 800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie h->id_ = state->next_id_++; 810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie lock.unlock(); 820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp timestamp; 840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie uint64_t current_id = 0; 860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (completion* current_completion = *state->current_completion_) 870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie current_id = current_completion->id_; 880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie write_line( 900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie "@asio|%llu.%06llu|%llu*%llu|%.20s@%p.%.50s\n", 910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie timestamp.seconds, timestamp.microseconds, 920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie current_id, h->id_, object_type, object, op_name); 930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiehandler_tracking::completion::completion(handler_tracking::tracked_handler* h) 960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : id_(h->id_), 970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie invoked_(false), 980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie next_(*get_state()->current_completion_) 990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *get_state()->current_completion_ = this; 1010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 1020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiehandler_tracking::completion::~completion() 1040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (id_) 1060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp timestamp; 1080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie write_line( 1100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie "@asio|%llu.%06llu|%c%llu|\n", 1110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie timestamp.seconds, timestamp.microseconds, 1120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie invoked_ ? '!' : '~', id_); 1130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *get_state()->current_completion_ = next_; 1160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 1170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::completion::invocation_begin() 1190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp timestamp; 1210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie write_line( 1230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie "@asio|%llu.%06llu|>%llu|\n", 1240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie timestamp.seconds, timestamp.microseconds, id_); 1250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie invoked_ = true; 1270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 1280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::completion::invocation_begin( 1300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::error_code& ec) 1310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp timestamp; 1330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie write_line( 1350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie "@asio|%llu.%06llu|>%llu|ec=%.20s:%d\n", 1360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie timestamp.seconds, timestamp.microseconds, 1370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie id_, ec.category().name(), ec.value()); 1380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie invoked_ = true; 1400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 1410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::completion::invocation_begin( 1430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::error_code& ec, std::size_t bytes_transferred) 1440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp timestamp; 1460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie write_line( 1480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,bytes_transferred=%llu\n", 1490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie timestamp.seconds, timestamp.microseconds, 1500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie id_, ec.category().name(), ec.value(), 1510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static_cast<uint64_t>(bytes_transferred)); 1520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie invoked_ = true; 1540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 1550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::completion::invocation_begin( 1570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::error_code& ec, int signal_number) 1580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp timestamp; 1600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie write_line( 1620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,signal_number=%d\n", 1630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie timestamp.seconds, timestamp.microseconds, 1640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie id_, ec.category().name(), ec.value(), signal_number); 1650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie invoked_ = true; 1670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 1680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::completion::invocation_begin( 1700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::error_code& ec, const char* arg) 1710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp timestamp; 1730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie write_line( 1750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,%.50s\n", 1760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie timestamp.seconds, timestamp.microseconds, 1770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie id_, ec.category().name(), ec.value(), arg); 1780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie invoked_ = true; 1800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 1810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::completion::invocation_end() 1830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (id_) 1850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp timestamp; 1870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie write_line( 1890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie "@asio|%llu.%06llu|<%llu|\n", 1900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie timestamp.seconds, timestamp.microseconds, id_); 1910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie id_ = 0; 1930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 1950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::operation(const char* object_type, 1970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void* object, const char* op_name) 1980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static tracking_state* state = get_state(); 2000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_tracking_timestamp timestamp; 2020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie unsigned long long current_id = 0; 2040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (completion* current_completion = *state->current_completion_) 2050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie current_id = current_completion->id_; 2060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie write_line( 2080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie "@asio|%llu.%06llu|%llu|%.20s@%p.%.50s\n", 2090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie timestamp.seconds, timestamp.microseconds, 2100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie current_id, object_type, object, op_name); 2110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 2120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffievoid handler_tracking::write_line(const char* format, ...) 2140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 2150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie using namespace std; // For sprintf (or equivalent). 2160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie va_list args; 2180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie va_start(args, format); 2190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie char line[256] = ""; 2210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#if defined(ASIO_HAS_SECURE_RTL) 2220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie int length = vsprintf_s(line, sizeof(line), format, args); 2230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#else // defined(ASIO_HAS_SECURE_RTL) 2240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie int length = vsprintf(line, format, args); 2250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // defined(ASIO_HAS_SECURE_RTL) 2260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie va_end(args); 2280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ::write(STDERR_FILENO, line, length); 2300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 2310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace detail 2330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace asio 2340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/pop_options.hpp" 2360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // defined(ASIO_ENABLE_HANDLER_TRACKING) 2380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP 240