add boost on mac
This commit is contained in:
541
macx64/include/boost/log/sinks/basic_sink_frontend.hpp
Normal file
541
macx64/include/boost/log/sinks/basic_sink_frontend.hpp
Normal file
@@ -0,0 +1,541 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file basic_sink_frontend.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 14.07.2009
|
||||
*
|
||||
* The header contains implementation of a base class for sink frontends.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SINKS_BASIC_SINK_FRONTEND_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SINKS_BASIC_SINK_FRONTEND_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/code_conversion.hpp>
|
||||
#include <boost/log/detail/attachable_sstream_buf.hpp>
|
||||
#include <boost/log/detail/fake_mutex.hpp>
|
||||
#include <boost/log/core/record_view.hpp>
|
||||
#include <boost/log/sinks/sink.hpp>
|
||||
#include <boost/log/sinks/frontend_requirements.hpp>
|
||||
#include <boost/log/expressions/filter.hpp>
|
||||
#include <boost/log/expressions/formatter.hpp>
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <boost/log/detail/locks.hpp>
|
||||
#include <boost/log/detail/light_rw_mutex.hpp>
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sinks {
|
||||
|
||||
//! A base class for a logging sink frontend
|
||||
class BOOST_LOG_NO_VTABLE basic_sink_frontend :
|
||||
public sink
|
||||
{
|
||||
//! Base type
|
||||
typedef sink base_type;
|
||||
|
||||
public:
|
||||
//! An exception handler type
|
||||
typedef base_type::exception_handler_type exception_handler_type;
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
protected:
|
||||
//! Mutex type
|
||||
typedef boost::log::aux::light_rw_mutex mutex_type;
|
||||
|
||||
private:
|
||||
//! Synchronization mutex
|
||||
mutable mutex_type m_Mutex;
|
||||
#endif
|
||||
|
||||
private:
|
||||
//! Filter
|
||||
filter m_Filter;
|
||||
//! Exception handler
|
||||
exception_handler_type m_ExceptionHandler;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Initializing constructor
|
||||
*
|
||||
* \param cross_thread The flag indicates whether the sink passes log records between different threads
|
||||
*/
|
||||
explicit basic_sink_frontend(bool cross_thread) : sink(cross_thread)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method sets sink-specific filter functional object
|
||||
*/
|
||||
template< typename FunT >
|
||||
void set_filter(FunT const& filter)
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< mutex_type > lock(m_Mutex);)
|
||||
m_Filter = filter;
|
||||
}
|
||||
/*!
|
||||
* The method resets the filter
|
||||
*/
|
||||
void reset_filter()
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< mutex_type > lock(m_Mutex);)
|
||||
m_Filter.reset();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method sets an exception handler function
|
||||
*/
|
||||
template< typename FunT >
|
||||
void set_exception_handler(FunT const& handler)
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< mutex_type > lock(m_Mutex);)
|
||||
m_ExceptionHandler = handler;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method resets the exception handler function
|
||||
*/
|
||||
void reset_exception_handler()
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< mutex_type > lock(m_Mutex);)
|
||||
m_ExceptionHandler.clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method returns \c true if no filter is set or the attribute values pass the filter
|
||||
*
|
||||
* \param attrs A set of attribute values of a logging record
|
||||
*/
|
||||
bool will_consume(attribute_value_set const& attrs)
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< mutex_type > lock(m_Mutex);)
|
||||
try
|
||||
{
|
||||
return m_Filter(attrs);
|
||||
}
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
catch (thread_interrupted&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
catch (...)
|
||||
{
|
||||
if (m_ExceptionHandler.empty())
|
||||
throw;
|
||||
m_ExceptionHandler();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
//! Returns reference to the frontend mutex
|
||||
mutex_type& frontend_mutex() const { return m_Mutex; }
|
||||
#endif
|
||||
|
||||
//! Returns reference to the exception handler
|
||||
exception_handler_type& exception_handler() { return m_ExceptionHandler; }
|
||||
//! Returns reference to the exception handler
|
||||
exception_handler_type const& exception_handler() const { return m_ExceptionHandler; }
|
||||
|
||||
//! Feeds log record to the backend
|
||||
template< typename BackendMutexT, typename BackendT >
|
||||
void feed_record(record_view const& rec, BackendMutexT& backend_mutex, BackendT& backend)
|
||||
{
|
||||
try
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< BackendMutexT > lock(backend_mutex);)
|
||||
backend.consume(rec);
|
||||
}
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
catch (thread_interrupted&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
catch (...)
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< mutex_type > lock(m_Mutex);)
|
||||
if (m_ExceptionHandler.empty())
|
||||
throw;
|
||||
m_ExceptionHandler();
|
||||
}
|
||||
}
|
||||
|
||||
//! Attempts to feeds log record to the backend, does not block if \a backend_mutex is locked
|
||||
template< typename BackendMutexT, typename BackendT >
|
||||
bool try_feed_record(record_view const& rec, BackendMutexT& backend_mutex, BackendT& backend)
|
||||
{
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
try
|
||||
{
|
||||
if (!backend_mutex.try_lock())
|
||||
return false;
|
||||
}
|
||||
catch (thread_interrupted&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
boost::log::aux::shared_lock_guard< mutex_type > frontend_lock(this->frontend_mutex());
|
||||
if (this->exception_handler().empty())
|
||||
throw;
|
||||
this->exception_handler()();
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::log::aux::exclusive_auto_unlocker< BackendMutexT > unlocker(backend_mutex);
|
||||
#endif
|
||||
// No need to lock anything in the feed_record method
|
||||
boost::log::aux::fake_mutex m;
|
||||
feed_record(rec, m, backend);
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Flushes record buffers in the backend, if one supports it
|
||||
template< typename BackendMutexT, typename BackendT >
|
||||
void flush_backend(BackendMutexT& backend_mutex, BackendT& backend)
|
||||
{
|
||||
typedef typename BackendT::frontend_requirements frontend_requirements;
|
||||
flush_backend_impl(backend_mutex, backend,
|
||||
typename has_requirement< frontend_requirements, flushing >::type());
|
||||
}
|
||||
|
||||
private:
|
||||
//! Flushes record buffers in the backend (the actual implementation)
|
||||
template< typename BackendMutexT, typename BackendT >
|
||||
void flush_backend_impl(BackendMutexT& backend_mutex, BackendT& backend, mpl::true_)
|
||||
{
|
||||
try
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< BackendMutexT > lock(backend_mutex);)
|
||||
backend.flush();
|
||||
}
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
catch (thread_interrupted&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
catch (...)
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< mutex_type > lock(m_Mutex);)
|
||||
if (m_ExceptionHandler.empty())
|
||||
throw;
|
||||
m_ExceptionHandler();
|
||||
}
|
||||
}
|
||||
//! Flushes record buffers in the backend (stub for backends that don't support flushing)
|
||||
template< typename BackendMutexT, typename BackendT >
|
||||
void flush_backend_impl(BackendMutexT&, BackendT&, mpl::false_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//! A base class for a logging sink frontend with formatting support
|
||||
template< typename CharT >
|
||||
class BOOST_LOG_NO_VTABLE basic_formatting_sink_frontend :
|
||||
public basic_sink_frontend
|
||||
{
|
||||
typedef basic_sink_frontend base_type;
|
||||
|
||||
public:
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! Formatted string type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
|
||||
//! Formatter function object type
|
||||
typedef basic_formatter< char_type > formatter_type;
|
||||
//! Output stream type
|
||||
typedef typename formatter_type::stream_type stream_type;
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
protected:
|
||||
//! Mutex type
|
||||
typedef typename base_type::mutex_type mutex_type;
|
||||
#endif
|
||||
|
||||
private:
|
||||
struct formatting_context
|
||||
{
|
||||
class cleanup_guard
|
||||
{
|
||||
private:
|
||||
formatting_context& m_context;
|
||||
|
||||
public:
|
||||
explicit cleanup_guard(formatting_context& ctx) BOOST_NOEXCEPT : m_context(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
~cleanup_guard()
|
||||
{
|
||||
m_context.m_FormattedRecord.clear();
|
||||
m_context.m_FormattingStream.rdbuf()->max_size(m_context.m_FormattedRecord.max_size());
|
||||
m_context.m_FormattingStream.rdbuf()->storage_overflow(false);
|
||||
m_context.m_FormattingStream.clear();
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(cleanup_guard(cleanup_guard const&))
|
||||
BOOST_DELETED_FUNCTION(cleanup_guard& operator=(cleanup_guard const&))
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
//! Object version
|
||||
const unsigned int m_Version;
|
||||
#endif
|
||||
//! Formatted log record storage
|
||||
string_type m_FormattedRecord;
|
||||
//! Formatting stream
|
||||
stream_type m_FormattingStream;
|
||||
//! Formatter functor
|
||||
formatter_type m_Formatter;
|
||||
|
||||
formatting_context() :
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
m_Version(0),
|
||||
#endif
|
||||
m_FormattingStream(m_FormattedRecord)
|
||||
{
|
||||
m_FormattingStream.exceptions(std::ios_base::badbit | std::ios_base::failbit);
|
||||
}
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
formatting_context(unsigned int version, std::locale const& loc, formatter_type const& formatter) :
|
||||
m_Version(version),
|
||||
m_FormattingStream(m_FormattedRecord),
|
||||
m_Formatter(formatter)
|
||||
{
|
||||
m_FormattingStream.exceptions(std::ios_base::badbit | std::ios_base::failbit);
|
||||
m_FormattingStream.imbue(loc);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
private:
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
//! State version
|
||||
volatile unsigned int m_Version;
|
||||
|
||||
//! Formatter functor
|
||||
formatter_type m_Formatter;
|
||||
//! Locale to perform formatting
|
||||
std::locale m_Locale;
|
||||
|
||||
//! Formatting state
|
||||
thread_specific_ptr< formatting_context > m_pContext;
|
||||
|
||||
#else
|
||||
|
||||
//! Formatting state
|
||||
formatting_context m_Context;
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Initializing constructor
|
||||
*
|
||||
* \param cross_thread The flag indicates whether the sink passes log records between different threads
|
||||
*/
|
||||
explicit basic_formatting_sink_frontend(bool cross_thread) :
|
||||
basic_sink_frontend(cross_thread)
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
, m_Version(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method sets sink-specific formatter function object
|
||||
*/
|
||||
template< typename FunT >
|
||||
void set_formatter(FunT const& formatter)
|
||||
{
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
boost::log::aux::exclusive_lock_guard< mutex_type > lock(this->frontend_mutex());
|
||||
m_Formatter = formatter;
|
||||
++m_Version;
|
||||
#else
|
||||
m_Context.m_Formatter = formatter;
|
||||
#endif
|
||||
}
|
||||
/*!
|
||||
* The method resets the formatter
|
||||
*/
|
||||
void reset_formatter()
|
||||
{
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
boost::log::aux::exclusive_lock_guard< mutex_type > lock(this->frontend_mutex());
|
||||
m_Formatter.reset();
|
||||
++m_Version;
|
||||
#else
|
||||
m_Context.m_Formatter.reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method returns the current locale used for formatting
|
||||
*/
|
||||
std::locale getloc() const
|
||||
{
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
boost::log::aux::exclusive_lock_guard< mutex_type > lock(this->frontend_mutex());
|
||||
return m_Locale;
|
||||
#else
|
||||
return m_Context.m_FormattingStream.getloc();
|
||||
#endif
|
||||
}
|
||||
/*!
|
||||
* The method sets the locale used for formatting
|
||||
*/
|
||||
void imbue(std::locale const& loc)
|
||||
{
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
boost::log::aux::exclusive_lock_guard< mutex_type > lock(this->frontend_mutex());
|
||||
m_Locale = loc;
|
||||
++m_Version;
|
||||
#else
|
||||
m_Context.m_FormattingStream.imbue(loc);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
//! Returns reference to the formatter
|
||||
formatter_type& formatter()
|
||||
{
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
return m_Formatter;
|
||||
#else
|
||||
return m_Context.m_Formatter;
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Feeds log record to the backend
|
||||
template< typename BackendMutexT, typename BackendT >
|
||||
void feed_record(record_view const& rec, BackendMutexT& backend_mutex, BackendT& backend)
|
||||
{
|
||||
formatting_context* context;
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
context = m_pContext.get();
|
||||
if (!context || context->m_Version != m_Version)
|
||||
{
|
||||
{
|
||||
boost::log::aux::shared_lock_guard< mutex_type > lock(this->frontend_mutex());
|
||||
context = new formatting_context(m_Version, m_Locale, m_Formatter);
|
||||
}
|
||||
m_pContext.reset(context);
|
||||
}
|
||||
#else
|
||||
context = &m_Context;
|
||||
#endif
|
||||
|
||||
typename formatting_context::cleanup_guard cleanup(*context);
|
||||
|
||||
try
|
||||
{
|
||||
// Perform the formatting
|
||||
context->m_Formatter(rec, context->m_FormattingStream);
|
||||
context->m_FormattingStream.flush();
|
||||
|
||||
// Feed the record
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< BackendMutexT > lock(backend_mutex);)
|
||||
backend.consume(rec, context->m_FormattedRecord);
|
||||
}
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
catch (thread_interrupted&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
catch (...)
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< mutex_type > lock(this->frontend_mutex());)
|
||||
if (this->exception_handler().empty())
|
||||
throw;
|
||||
this->exception_handler()();
|
||||
}
|
||||
}
|
||||
|
||||
//! Attempts to feeds log record to the backend, does not block if \a backend_mutex is locked
|
||||
template< typename BackendMutexT, typename BackendT >
|
||||
bool try_feed_record(record_view const& rec, BackendMutexT& backend_mutex, BackendT& backend)
|
||||
{
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
try
|
||||
{
|
||||
if (!backend_mutex.try_lock())
|
||||
return false;
|
||||
}
|
||||
catch (thread_interrupted&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
boost::log::aux::shared_lock_guard< mutex_type > frontend_lock(this->frontend_mutex());
|
||||
if (this->exception_handler().empty())
|
||||
throw;
|
||||
this->exception_handler()();
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::log::aux::exclusive_auto_unlocker< BackendMutexT > unlocker(backend_mutex);
|
||||
#endif
|
||||
// No need to lock anything in the feed_record method
|
||||
boost::log::aux::fake_mutex m;
|
||||
feed_record(rec, m, backend);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
namespace aux {
|
||||
|
||||
template<
|
||||
typename BackendT,
|
||||
bool RequiresFormattingV = has_requirement<
|
||||
typename BackendT::frontend_requirements,
|
||||
formatted_records
|
||||
>::value
|
||||
>
|
||||
struct make_sink_frontend_base
|
||||
{
|
||||
typedef basic_sink_frontend type;
|
||||
};
|
||||
template< typename BackendT >
|
||||
struct make_sink_frontend_base< BackendT, true >
|
||||
{
|
||||
typedef basic_formatting_sink_frontend< typename BackendT::char_type > type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
} // namespace sinks
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SINKS_BASIC_SINK_FRONTEND_HPP_INCLUDED_
|
||||
Reference in New Issue
Block a user