update boost
This commit is contained in:
@@ -26,7 +26,6 @@
|
||||
#error Boost.Log: Asynchronous sink frontend is only supported in multithreaded environment
|
||||
#endif
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/atomic.hpp>
|
||||
@@ -56,12 +55,13 @@ namespace sinks {
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1(n, data)\
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1(z, n, data)\
|
||||
template< typename T0 >\
|
||||
explicit asynchronous_sink(T0 const& arg0, typename boost::log::aux::enable_if_named_parameters< T0, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :\
|
||||
base_type(true),\
|
||||
queue_base_type(arg0),\
|
||||
m_pBackend(boost::make_shared< sink_backend_type >(arg0)),\
|
||||
m_ActiveOperation(idle),\
|
||||
m_StopRequested(false),\
|
||||
m_FlushRequested(false)\
|
||||
{\
|
||||
@@ -73,6 +73,7 @@ namespace sinks {
|
||||
base_type(true),\
|
||||
queue_base_type(arg0),\
|
||||
m_pBackend(backend),\
|
||||
m_ActiveOperation(idle),\
|
||||
m_StopRequested(false),\
|
||||
m_FlushRequested(false)\
|
||||
{\
|
||||
@@ -80,32 +81,34 @@ namespace sinks {
|
||||
start_feeding_thread();\
|
||||
}
|
||||
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N(n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
|
||||
explicit asynchronous_sink(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg)) :\
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N(z, n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS_Z(z, n, typename T) >\
|
||||
explicit asynchronous_sink(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, const& arg)) :\
|
||||
base_type(true),\
|
||||
queue_base_type((BOOST_PP_ENUM_PARAMS(n, arg))),\
|
||||
m_pBackend(boost::make_shared< sink_backend_type >(BOOST_PP_ENUM_PARAMS(n, arg))),\
|
||||
queue_base_type((BOOST_PP_ENUM_PARAMS_Z(z, n, arg))),\
|
||||
m_pBackend(boost::make_shared< sink_backend_type >(BOOST_PP_ENUM_PARAMS_Z(z, n, arg))),\
|
||||
m_ActiveOperation(idle),\
|
||||
m_StopRequested(false),\
|
||||
m_FlushRequested(false)\
|
||||
{\
|
||||
if ((BOOST_PP_ENUM_PARAMS(n, arg))[keywords::start_thread | true])\
|
||||
if ((BOOST_PP_ENUM_PARAMS_Z(z, n, arg))[keywords::start_thread | true])\
|
||||
start_feeding_thread();\
|
||||
}\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
|
||||
explicit asynchronous_sink(shared_ptr< sink_backend_type > const& backend, BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg)) :\
|
||||
template< BOOST_PP_ENUM_PARAMS_Z(z, n, typename T) >\
|
||||
explicit asynchronous_sink(shared_ptr< sink_backend_type > const& backend, BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, const& arg)) :\
|
||||
base_type(true),\
|
||||
queue_base_type((BOOST_PP_ENUM_PARAMS(n, arg))),\
|
||||
queue_base_type((BOOST_PP_ENUM_PARAMS_Z(z, n, arg))),\
|
||||
m_pBackend(backend),\
|
||||
m_ActiveOperation(idle),\
|
||||
m_StopRequested(false),\
|
||||
m_FlushRequested(false)\
|
||||
{\
|
||||
if ((BOOST_PP_ENUM_PARAMS(n, arg))[keywords::start_thread | true])\
|
||||
if ((BOOST_PP_ENUM_PARAMS_Z(z, n, arg))[keywords::start_thread | true])\
|
||||
start_feeding_thread();\
|
||||
}
|
||||
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL(z, n, data)\
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1, BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N)(n, data)
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1, BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N)(z, n, data)
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
@@ -113,7 +116,13 @@ namespace sinks {
|
||||
* \brief Asynchronous logging sink frontend
|
||||
*
|
||||
* The frontend starts a separate thread on construction. All logging records are passed
|
||||
* to the backend in this dedicated thread only.
|
||||
* to the backend in this dedicated thread.
|
||||
*
|
||||
* The user can prevent spawning the internal thread by specifying \c start_thread parameter
|
||||
* with the value of \c false on construction. In this case log records will be buffered
|
||||
* in the internal queue until the user calls \c run, \c feed_records or \c flush in his own
|
||||
* thread. Log record queueing strategy is specified in the \c QueueingStrategyT template
|
||||
* parameter.
|
||||
*/
|
||||
template< typename SinkBackendT, typename QueueingStrategyT = unbounded_fifo_queue >
|
||||
class asynchronous_sink :
|
||||
@@ -129,51 +138,53 @@ private:
|
||||
//! Frontend synchronization mutex type
|
||||
typedef typename base_type::mutex_type frontend_mutex_type;
|
||||
|
||||
//! A scope guard that implements thread ID management
|
||||
class scoped_thread_id
|
||||
//! Operation bit mask
|
||||
enum operation
|
||||
{
|
||||
idle = 0u,
|
||||
feeding_records = 1u,
|
||||
flushing = 3u
|
||||
};
|
||||
|
||||
//! Function object to run the log record feeding thread
|
||||
class run_func
|
||||
{
|
||||
public:
|
||||
typedef void result_type;
|
||||
|
||||
private:
|
||||
asynchronous_sink* m_self;
|
||||
|
||||
public:
|
||||
explicit run_func(asynchronous_sink* self) BOOST_NOEXCEPT : m_self(self)
|
||||
{
|
||||
}
|
||||
|
||||
result_type operator()() const
|
||||
{
|
||||
m_self->run();
|
||||
}
|
||||
};
|
||||
|
||||
//! A scope guard that implements active operation management
|
||||
class scoped_feeding_operation
|
||||
{
|
||||
private:
|
||||
frontend_mutex_type& m_Mutex;
|
||||
condition_variable_any& m_Cond;
|
||||
thread::id& m_ThreadID;
|
||||
boost::atomic< bool >& m_StopRequested;
|
||||
asynchronous_sink& m_self;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
scoped_thread_id(frontend_mutex_type& mut, condition_variable_any& cond, thread::id& tid, boost::atomic< bool >& sr)
|
||||
: m_Mutex(mut), m_Cond(cond), m_ThreadID(tid), m_StopRequested(sr)
|
||||
explicit scoped_feeding_operation(asynchronous_sink& self) : m_self(self)
|
||||
{
|
||||
lock_guard< frontend_mutex_type > lock(m_Mutex);
|
||||
if (m_ThreadID != thread::id())
|
||||
BOOST_LOG_THROW_DESCR(unexpected_call, "Asynchronous sink frontend already runs a record feeding thread");
|
||||
m_ThreadID = this_thread::get_id();
|
||||
}
|
||||
//! Initializing constructor
|
||||
scoped_thread_id(unique_lock< frontend_mutex_type >& l, condition_variable_any& cond, thread::id& tid, boost::atomic< bool >& sr)
|
||||
: m_Mutex(*l.mutex()), m_Cond(cond), m_ThreadID(tid), m_StopRequested(sr)
|
||||
{
|
||||
unique_lock< frontend_mutex_type > lock(move(l));
|
||||
if (m_ThreadID != thread::id())
|
||||
BOOST_LOG_THROW_DESCR(unexpected_call, "Asynchronous sink frontend already runs a record feeding thread");
|
||||
m_ThreadID = this_thread::get_id();
|
||||
}
|
||||
//! Destructor
|
||||
~scoped_thread_id()
|
||||
~scoped_feeding_operation()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock_guard< frontend_mutex_type > lock(m_Mutex);
|
||||
m_StopRequested.store(false, boost::memory_order_release);
|
||||
m_ThreadID = thread::id();
|
||||
m_Cond.notify_all();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
m_self.complete_feeding_operation();
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(scoped_thread_id(scoped_thread_id const&))
|
||||
BOOST_DELETED_FUNCTION(scoped_thread_id& operator= (scoped_thread_id const&))
|
||||
BOOST_DELETED_FUNCTION(scoped_feeding_operation(scoped_feeding_operation const&))
|
||||
BOOST_DELETED_FUNCTION(scoped_feeding_operation& operator= (scoped_feeding_operation const&))
|
||||
};
|
||||
|
||||
//! A scope guard that resets a flag on destructor
|
||||
@@ -194,7 +205,7 @@ private:
|
||||
try
|
||||
{
|
||||
lock_guard< frontend_mutex_type > lock(m_Mutex);
|
||||
m_Flag.store(false, boost::memory_order_release);
|
||||
m_Flag.store(false, boost::memory_order_relaxed);
|
||||
m_Cond.notify_all();
|
||||
}
|
||||
catch (...)
|
||||
@@ -233,11 +244,11 @@ private:
|
||||
|
||||
//! Dedicated record feeding thread
|
||||
thread m_DedicatedFeedingThread;
|
||||
//! Feeding thread ID
|
||||
thread::id m_FeedingThreadID;
|
||||
//! Condition variable to implement blocking operations
|
||||
condition_variable_any m_BlockCond;
|
||||
|
||||
//! Currently active operation
|
||||
operation m_ActiveOperation;
|
||||
//! The flag indicates that the feeding loop has to be stopped
|
||||
boost::atomic< bool > m_StopRequested;
|
||||
//! The flag indicates that queue flush has been requested
|
||||
@@ -251,11 +262,12 @@ public:
|
||||
* \param start_thread If \c true, the frontend creates a thread to feed
|
||||
* log records to the backend. Otherwise no thread is
|
||||
* started and it is assumed that the user will call
|
||||
* either \c run or \c feed_records himself.
|
||||
* \c run, \c feed_records or \c flush himself.
|
||||
*/
|
||||
asynchronous_sink(bool start_thread = true) :
|
||||
explicit asynchronous_sink(bool start_thread = true) :
|
||||
base_type(true),
|
||||
m_pBackend(boost::make_shared< sink_backend_type >()),
|
||||
m_ActiveOperation(idle),
|
||||
m_StopRequested(false),
|
||||
m_FlushRequested(false)
|
||||
{
|
||||
@@ -269,13 +281,14 @@ public:
|
||||
* \param start_thread If \c true, the frontend creates a thread to feed
|
||||
* log records to the backend. Otherwise no thread is
|
||||
* started and it is assumed that the user will call
|
||||
* either \c run or \c feed_records himself.
|
||||
* \c run, \c feed_records or \c flush himself.
|
||||
*
|
||||
* \pre \a backend is not \c NULL.
|
||||
*/
|
||||
explicit asynchronous_sink(shared_ptr< sink_backend_type > const& backend, bool start_thread = true) :
|
||||
base_type(true),
|
||||
m_pBackend(backend),
|
||||
m_ActiveOperation(idle),
|
||||
m_StopRequested(false),
|
||||
m_FlushRequested(false)
|
||||
{
|
||||
@@ -292,7 +305,7 @@ public:
|
||||
* \li start_thread - If \c true, the frontend creates a thread to feed
|
||||
* log records to the backend. Otherwise no thread is
|
||||
* started and it is assumed that the user will call
|
||||
* either \c run or \c feed_records himself.
|
||||
* \c run, \c feed_records or \c flush himself.
|
||||
*/
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL, ~)
|
||||
@@ -304,7 +317,7 @@ public:
|
||||
/*!
|
||||
* Destructor. Implicitly stops the dedicated feeding thread, if one is running.
|
||||
*/
|
||||
~asynchronous_sink() BOOST_NOEXCEPT
|
||||
~asynchronous_sink() BOOST_NOEXCEPT BOOST_OVERRIDE
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -328,7 +341,7 @@ public:
|
||||
/*!
|
||||
* Enqueues the log record to the backend
|
||||
*/
|
||||
void consume(record_view const& rec)
|
||||
void consume(record_view const& rec) BOOST_OVERRIDE
|
||||
{
|
||||
if (BOOST_UNLIKELY(m_FlushRequested.load(boost::memory_order_acquire)))
|
||||
{
|
||||
@@ -343,7 +356,7 @@ public:
|
||||
/*!
|
||||
* The method attempts to pass logging record to the backend
|
||||
*/
|
||||
bool try_consume(record_view const& rec)
|
||||
bool try_consume(record_view const& rec) BOOST_OVERRIDE
|
||||
{
|
||||
if (!m_FlushRequested.load(boost::memory_order_acquire))
|
||||
{
|
||||
@@ -365,7 +378,13 @@ public:
|
||||
void run()
|
||||
{
|
||||
// First check that no other thread is running
|
||||
scoped_thread_id guard(base_type::frontend_mutex(), m_BlockCond, m_FeedingThreadID, m_StopRequested);
|
||||
{
|
||||
unique_lock< frontend_mutex_type > lock(base_type::frontend_mutex());
|
||||
if (start_feeding_operation(lock, feeding_records))
|
||||
return;
|
||||
}
|
||||
|
||||
scoped_feeding_operation guard(*this);
|
||||
|
||||
// Now start the feeding loop
|
||||
while (true)
|
||||
@@ -384,40 +403,42 @@ public:
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method softly interrupts record feeding loop. This method must be called when the \c run
|
||||
* method execution has to be interrupted. Unlike regular thread interruption, calling
|
||||
* \c stop will not interrupt the record processing in the middle. Instead, the sink frontend
|
||||
* will attempt to finish its business with the record in progress and return afterwards.
|
||||
* This method can be called either if the sink was created with a dedicated thread,
|
||||
* or if the feeding loop was initiated by user.
|
||||
* The method softly interrupts record feeding loop. This method must be called when \c run,
|
||||
* \c feed_records or \c flush method execution has to be interrupted. Unlike regular thread
|
||||
* interruption, calling \c stop will not interrupt the record processing in the middle.
|
||||
* Instead, the sink frontend will attempt to finish its business with the record in progress
|
||||
* and return afterwards. This method can be called either if the sink was created with
|
||||
* an internal dedicated thread, or if the feeding loop was initiated by user.
|
||||
*
|
||||
* If no record feeding operation is in progress, calling \c stop marks the sink frontend
|
||||
* so that the next feeding operation stops immediately.
|
||||
*
|
||||
* \note Returning from this method does not guarantee that there are no records left buffered
|
||||
* in the sink frontend. It is possible that log records keep coming during and after this
|
||||
* method is called. At some point of execution of this method log records stop being processed,
|
||||
* and all records that come after this point are put into the queue. These records will be
|
||||
* processed upon further calls to \c run or \c feed_records.
|
||||
*
|
||||
* \note If the record feeding loop is being run in a user's thread (i.e. \c start_thread was specified
|
||||
* as \c false on frontend construction), this method does not guarantee that upon return the thread
|
||||
* has returned from the record feeding loop or that it won't enter it in the future. The method
|
||||
* only ensures that the record feeding thread will eventually return from the feeding loop. It is
|
||||
* user's responsibility to synchronize with the user's record feeding thread.
|
||||
*/
|
||||
void stop()
|
||||
{
|
||||
unique_lock< frontend_mutex_type > lock(base_type::frontend_mutex());
|
||||
if (m_FeedingThreadID != thread::id() || m_DedicatedFeedingThread.joinable())
|
||||
boost::thread feeding_thread;
|
||||
{
|
||||
try
|
||||
{
|
||||
m_StopRequested.store(true, boost::memory_order_release);
|
||||
queue_base_type::interrupt_dequeue();
|
||||
while (m_StopRequested.load(boost::memory_order_acquire))
|
||||
m_BlockCond.wait(lock);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
m_StopRequested.store(false, boost::memory_order_release);
|
||||
throw;
|
||||
}
|
||||
lock_guard< frontend_mutex_type > lock(base_type::frontend_mutex());
|
||||
|
||||
lock.unlock();
|
||||
m_DedicatedFeedingThread.join();
|
||||
m_StopRequested.store(true, boost::memory_order_release);
|
||||
queue_base_type::interrupt_dequeue();
|
||||
|
||||
m_DedicatedFeedingThread.swap(feeding_thread);
|
||||
}
|
||||
|
||||
if (feeding_thread.joinable())
|
||||
feeding_thread.join();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -428,7 +449,13 @@ public:
|
||||
void feed_records()
|
||||
{
|
||||
// First check that no other thread is running
|
||||
scoped_thread_id guard(base_type::frontend_mutex(), m_BlockCond, m_FeedingThreadID, m_StopRequested);
|
||||
{
|
||||
unique_lock< frontend_mutex_type > lock(base_type::frontend_mutex());
|
||||
if (start_feeding_operation(lock, feeding_records))
|
||||
return;
|
||||
}
|
||||
|
||||
scoped_feeding_operation guard(*this);
|
||||
|
||||
// Now start the feeding loop
|
||||
do_feed_records();
|
||||
@@ -437,29 +464,31 @@ public:
|
||||
/*!
|
||||
* The method feeds all log records that may have been buffered to the backend and returns.
|
||||
* Unlike \c feed_records, in case of ordering queueing the method also feeds records
|
||||
* that were enqueued during the ordering window, attempting to empty the queue completely.
|
||||
* that were enqueued during the ordering window, attempting to drain the queue completely.
|
||||
*/
|
||||
void flush()
|
||||
void flush() BOOST_OVERRIDE
|
||||
{
|
||||
unique_lock< frontend_mutex_type > lock(base_type::frontend_mutex());
|
||||
if (m_FeedingThreadID != thread::id() || m_DedicatedFeedingThread.joinable())
|
||||
{
|
||||
// There is already a thread feeding records, let it do the job
|
||||
m_FlushRequested.store(true, boost::memory_order_release);
|
||||
queue_base_type::interrupt_dequeue();
|
||||
while (!m_StopRequested.load(boost::memory_order_acquire) && m_FlushRequested.load(boost::memory_order_acquire))
|
||||
m_BlockCond.wait(lock);
|
||||
unique_lock< frontend_mutex_type > lock(base_type::frontend_mutex());
|
||||
if (static_cast< unsigned int >(m_ActiveOperation & feeding_records) != 0u)
|
||||
{
|
||||
// There is already a thread feeding records, let it do the job
|
||||
m_FlushRequested.store(true, boost::memory_order_release);
|
||||
queue_base_type::interrupt_dequeue();
|
||||
while (!m_StopRequested.load(boost::memory_order_acquire) && m_FlushRequested.load(boost::memory_order_acquire))
|
||||
m_BlockCond.wait(lock);
|
||||
|
||||
// The condition may have been signalled when the feeding thread was finishing.
|
||||
// In that case records may not have been flushed, and we do the flush ourselves.
|
||||
if (m_FeedingThreadID != thread::id())
|
||||
return;
|
||||
// The condition may have been signalled when the feeding operation was finishing.
|
||||
// In that case records may not have been flushed, and we do the flush ourselves.
|
||||
if (m_ActiveOperation != idle)
|
||||
return;
|
||||
}
|
||||
|
||||
m_ActiveOperation = flushing;
|
||||
m_FlushRequested.store(true, boost::memory_order_relaxed);
|
||||
}
|
||||
|
||||
m_FlushRequested.store(true, boost::memory_order_release);
|
||||
|
||||
// Flush records ourselves. The guard releases the lock.
|
||||
scoped_thread_id guard(lock, m_BlockCond, m_FeedingThreadID, m_StopRequested);
|
||||
scoped_feeding_operation guard(*this);
|
||||
|
||||
do_feed_records();
|
||||
}
|
||||
@@ -469,7 +498,44 @@ private:
|
||||
//! The method spawns record feeding thread
|
||||
void start_feeding_thread()
|
||||
{
|
||||
boost::thread(boost::bind(&asynchronous_sink::run, this)).swap(m_DedicatedFeedingThread);
|
||||
boost::thread(run_func(this)).swap(m_DedicatedFeedingThread);
|
||||
}
|
||||
|
||||
//! Starts record feeding operation. The method blocks or throws if another feeding operation is in progress.
|
||||
bool start_feeding_operation(unique_lock< frontend_mutex_type >& lock, operation op)
|
||||
{
|
||||
while (m_ActiveOperation != idle)
|
||||
{
|
||||
if (BOOST_UNLIKELY(op == feeding_records && m_ActiveOperation == feeding_records))
|
||||
BOOST_LOG_THROW_DESCR(unexpected_call, "Asynchronous sink frontend already runs a record feeding thread");
|
||||
|
||||
if (BOOST_UNLIKELY(m_StopRequested.load(boost::memory_order_relaxed)))
|
||||
{
|
||||
m_StopRequested.store(false, boost::memory_order_relaxed);
|
||||
return true;
|
||||
}
|
||||
|
||||
m_BlockCond.wait(lock);
|
||||
}
|
||||
|
||||
m_ActiveOperation = op;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//! Completes record feeding operation
|
||||
void complete_feeding_operation() BOOST_NOEXCEPT
|
||||
{
|
||||
try
|
||||
{
|
||||
lock_guard< frontend_mutex_type > lock(base_type::frontend_mutex());
|
||||
m_ActiveOperation = idle;
|
||||
m_StopRequested.store(false, boost::memory_order_relaxed);
|
||||
m_BlockCond.notify_all();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//! The record feeding loop
|
||||
|
||||
47
linx64/include/boost/log/sinks/auto_newline_mode.hpp
Normal file
47
linx64/include/boost/log/sinks/auto_newline_mode.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2019.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file sinks/auto_newline_mode.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 23.06.2019
|
||||
*
|
||||
* The header contains definition of auto-newline modes.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SINKS_AUTO_NEWLINE_MODE_HPP_INCLUDED_HPP_
|
||||
#define BOOST_LOG_SINKS_AUTO_NEWLINE_MODE_HPP_INCLUDED_HPP_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sinks {
|
||||
|
||||
//! The enum lists automatic trailing newline modes
|
||||
enum auto_newline_mode
|
||||
{
|
||||
disabled_auto_newline, //!< Do not insert automatic trailing newline characters
|
||||
always_insert, //!< Always insert automatic trailing newline characters
|
||||
insert_if_missing //!< Insert automatic trailing newline characters, if not present already
|
||||
};
|
||||
|
||||
} // namespace sinks
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SINKS_AUTO_NEWLINE_MODE_HPP_INCLUDED_HPP_
|
||||
@@ -15,7 +15,7 @@
|
||||
#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/type_traits/integral_constant.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/code_conversion.hpp>
|
||||
#include <boost/log/detail/attachable_sstream_buf.hpp>
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <boost/log/expressions/filter.hpp>
|
||||
#include <boost/log/expressions/formatter.hpp>
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/atomic.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <boost/log/detail/locks.hpp>
|
||||
@@ -122,7 +124,7 @@ public:
|
||||
*
|
||||
* \param attrs A set of attribute values of a logging record
|
||||
*/
|
||||
bool will_consume(attribute_value_set const& attrs)
|
||||
bool will_consume(attribute_value_set const& attrs) BOOST_OVERRIDE
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< mutex_type > lock(m_Mutex);)
|
||||
try
|
||||
@@ -222,7 +224,7 @@ protected:
|
||||
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_)
|
||||
void flush_backend_impl(BackendMutexT& backend_mutex, BackendT& backend, boost::true_type)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -245,7 +247,7 @@ private:
|
||||
}
|
||||
//! 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_)
|
||||
void flush_backend_impl(BackendMutexT&, BackendT&, boost::false_type)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -312,7 +314,7 @@ private:
|
||||
|
||||
formatting_context() :
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
m_Version(0),
|
||||
m_Version(0u),
|
||||
#endif
|
||||
m_FormattingStream(m_FormattedRecord)
|
||||
{
|
||||
@@ -334,7 +336,7 @@ private:
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
//! State version
|
||||
volatile unsigned int m_Version;
|
||||
boost::atomic< unsigned int > m_Version;
|
||||
|
||||
//! Formatter functor
|
||||
formatter_type m_Formatter;
|
||||
@@ -360,7 +362,7 @@ public:
|
||||
explicit basic_formatting_sink_frontend(bool cross_thread) :
|
||||
basic_sink_frontend(cross_thread)
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
, m_Version(0)
|
||||
, m_Version(0u)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
@@ -374,7 +376,7 @@ public:
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
boost::log::aux::exclusive_lock_guard< mutex_type > lock(this->frontend_mutex());
|
||||
m_Formatter = formatter;
|
||||
++m_Version;
|
||||
m_Version.opaque_add(1u, boost::memory_order_relaxed);
|
||||
#else
|
||||
m_Context.m_Formatter = formatter;
|
||||
#endif
|
||||
@@ -387,7 +389,7 @@ public:
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
boost::log::aux::exclusive_lock_guard< mutex_type > lock(this->frontend_mutex());
|
||||
m_Formatter.reset();
|
||||
++m_Version;
|
||||
m_Version.opaque_add(1u, boost::memory_order_relaxed);
|
||||
#else
|
||||
m_Context.m_Formatter.reset();
|
||||
#endif
|
||||
@@ -413,7 +415,7 @@ public:
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
boost::log::aux::exclusive_lock_guard< mutex_type > lock(this->frontend_mutex());
|
||||
m_Locale = loc;
|
||||
++m_Version;
|
||||
m_Version.opaque_add(1u, boost::memory_order_relaxed);
|
||||
#else
|
||||
m_Context.m_FormattingStream.imbue(loc);
|
||||
#endif
|
||||
@@ -438,11 +440,11 @@ protected:
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
context = m_pContext.get();
|
||||
if (!context || context->m_Version != m_Version)
|
||||
if (!context || context->m_Version != m_Version.load(boost::memory_order_relaxed))
|
||||
{
|
||||
{
|
||||
boost::log::aux::shared_lock_guard< mutex_type > lock(this->frontend_mutex());
|
||||
context = new formatting_context(m_Version, m_Locale, m_Formatter);
|
||||
context = new formatting_context(m_Version.load(boost::memory_order_relaxed), m_Locale, m_Formatter);
|
||||
}
|
||||
m_pContext.reset(context);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
#ifndef BOOST_LOG_SINKS_FRONTEND_REQUIREMENTS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SINKS_FRONTEND_REQUIREMENTS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/mpl/aux_/na.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/inherit.hpp>
|
||||
@@ -24,8 +27,7 @@
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
@@ -75,7 +77,7 @@ struct formatted_records {};
|
||||
*/
|
||||
struct flushing {};
|
||||
|
||||
#ifdef BOOST_LOG_DOXYGEN_PASS
|
||||
#if defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
/*!
|
||||
* The metafunction combines multiple requirement tags into one type. The resulting type will
|
||||
@@ -84,6 +86,24 @@ struct flushing {};
|
||||
template< typename... RequirementsT >
|
||||
struct combine_requirements;
|
||||
|
||||
#elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename... RequirementsT >
|
||||
struct combined_requirements :
|
||||
public RequirementsT...
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
template< typename... RequirementsT >
|
||||
struct combine_requirements
|
||||
{
|
||||
typedef sinks::aux::combined_requirements< RequirementsT... > type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template< BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_LOG_COMBINE_REQUIREMENTS_LIMIT, typename ReqT, mpl::na) >
|
||||
|
||||
@@ -46,20 +46,20 @@ namespace sinks {
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1(n, data)\
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1(z, n, data)\
|
||||
template< typename T0 >\
|
||||
explicit synchronous_sink(T0 const& arg0, typename boost::log::aux::enable_if_named_parameters< T0, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :\
|
||||
base_type(false),\
|
||||
m_pBackend(boost::make_shared< sink_backend_type >(arg0)) {}
|
||||
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N(n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
|
||||
explicit synchronous_sink(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg)) :\
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N(z, n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS_Z(z, n, typename T) >\
|
||||
explicit synchronous_sink(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, const& arg)) :\
|
||||
base_type(false),\
|
||||
m_pBackend(boost::make_shared< sink_backend_type >(BOOST_PP_ENUM_PARAMS(n, arg))) {}
|
||||
m_pBackend(boost::make_shared< sink_backend_type >(BOOST_PP_ENUM_PARAMS_Z(z, n, arg))) {}
|
||||
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL(z, n, data)\
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1, BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N)(n, data)
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1, BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N)(z, n, data)
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
@@ -148,7 +148,7 @@ public:
|
||||
/*!
|
||||
* Passes the log record to the backend
|
||||
*/
|
||||
void consume(record_view const& rec)
|
||||
void consume(record_view const& rec) BOOST_OVERRIDE
|
||||
{
|
||||
base_type::feed_record(rec, m_BackendMutex, *m_pBackend);
|
||||
}
|
||||
@@ -156,7 +156,7 @@ public:
|
||||
/*!
|
||||
* The method attempts to pass logging record to the backend
|
||||
*/
|
||||
bool try_consume(record_view const& rec)
|
||||
bool try_consume(record_view const& rec) BOOST_OVERRIDE
|
||||
{
|
||||
return base_type::try_feed_record(rec, m_BackendMutex, *m_pBackend);
|
||||
}
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
* may take considerable time to complete and may block both the calling thread and threads
|
||||
* attempting to put new records into the sink while this call is in progress.
|
||||
*/
|
||||
void flush()
|
||||
void flush() BOOST_OVERRIDE
|
||||
{
|
||||
base_type::flush_backend(m_BackendMutex, *m_pBackend);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <ostream>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/date_time/date_defs.hpp>
|
||||
#include <boost/date_time/special_defs.hpp>
|
||||
@@ -37,9 +38,11 @@
|
||||
#include <boost/log/keywords/rotation_size.hpp>
|
||||
#include <boost/log/keywords/time_based_rotation.hpp>
|
||||
#include <boost/log/keywords/enable_final_rotation.hpp>
|
||||
#include <boost/log/keywords/auto_newline_mode.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/light_function.hpp>
|
||||
#include <boost/log/detail/parameter_tools.hpp>
|
||||
#include <boost/log/sinks/auto_newline_mode.hpp>
|
||||
#include <boost/log/sinks/basic_sink_backend.hpp>
|
||||
#include <boost/log/sinks/frontend_requirements.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
@@ -64,6 +67,20 @@ enum scan_method
|
||||
scan_all //!< Scan for all files in the directory
|
||||
};
|
||||
|
||||
//! The structure contains filesystem scanning results
|
||||
struct scan_result
|
||||
{
|
||||
//! The number of found files
|
||||
uintmax_t found_count;
|
||||
//! If populated, the largest file counter that was used in the found file names
|
||||
boost::optional< unsigned int > last_file_counter;
|
||||
|
||||
scan_result() BOOST_NOEXCEPT :
|
||||
found_count(0u)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Base class for file collectors
|
||||
*
|
||||
@@ -79,7 +96,11 @@ struct BOOST_LOG_NO_VTABLE collector
|
||||
/*!
|
||||
* Virtual destructor
|
||||
*/
|
||||
#if !defined(BOOST_LOG_NO_CXX11_DEFAULTED_VIRTUAL_FUNCTIONS)
|
||||
BOOST_DEFAULTED_FUNCTION(virtual ~collector(), {})
|
||||
#else
|
||||
virtual ~collector() {}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* The function stores the specified file in the storage. May lead to an older file
|
||||
@@ -89,6 +110,13 @@ struct BOOST_LOG_NO_VTABLE collector
|
||||
*/
|
||||
virtual void store_file(filesystem::path const& src_path) = 0;
|
||||
|
||||
/*!
|
||||
* The function checks if the specified path refers to an existing file in the storage.
|
||||
*
|
||||
* \param src_path The path to be checked
|
||||
*/
|
||||
virtual bool is_in_storage(filesystem::path const& src_path) const = 0;
|
||||
|
||||
/*!
|
||||
* Scans the target directory for the files that have already been stored. The found
|
||||
* files are added to the collector in order to be tracked and erased, if needed.
|
||||
@@ -108,19 +136,17 @@ struct BOOST_LOG_NO_VTABLE collector
|
||||
* \param method The method of scanning. If \c no_scan is specified, the call has no effect.
|
||||
* \param pattern The file name pattern if \a method is \c scan_matching. Otherwise the parameter
|
||||
* is not used.
|
||||
* \param counter If not \c NULL and \a method is \c scan_matching, the method suggests initial value
|
||||
* of a file counter that may be used in the file name pattern. The parameter
|
||||
* is not used otherwise.
|
||||
* \return The number of found files.
|
||||
* \return The result of filesystem scanning. The last file counter is only populated if
|
||||
* \a method is \c scan_matching, the \a pattern contains %N placeholder, and at least
|
||||
* one file matching the pattern is found.
|
||||
*
|
||||
* \note In case if \a method is \c scan_matching the effect of this function is highly dependent
|
||||
* on the \a pattern definition. It is recommended to choose patterns with easily
|
||||
* distinguished placeholders (i.e. having delimiters between them). Otherwise
|
||||
* either some files can be mistakenly found or not found, which in turn may lead
|
||||
* to an incorrect file deletion.
|
||||
* to deletion of an unintended file.
|
||||
*/
|
||||
virtual uintmax_t scan_for_files(
|
||||
scan_method method, filesystem::path const& pattern = filesystem::path(), unsigned int* counter = 0) = 0;
|
||||
virtual scan_result scan_for_files(scan_method method, filesystem::path const& pattern = filesystem::path()) = 0;
|
||||
|
||||
BOOST_DELETED_FUNCTION(collector(collector const&))
|
||||
BOOST_DELETED_FUNCTION(collector& operator= (collector const&))
|
||||
@@ -234,8 +260,8 @@ private:
|
||||
monthday
|
||||
};
|
||||
|
||||
day_kind m_DayKind : 2;
|
||||
unsigned char m_Day : 6;
|
||||
unsigned char m_DayKind : 2; // contains day_kind values
|
||||
unsigned char m_Hour, m_Minute, m_Second;
|
||||
|
||||
mutable posix_time::ptime m_Previous;
|
||||
@@ -397,6 +423,8 @@ public:
|
||||
* sink backend destruction. By default, is \c true.
|
||||
* \li \c auto_flush - Specifies a flag, whether or not to automatically flush the file after each
|
||||
* written log record. By default, is \c false.
|
||||
* \li \c auto_newline_mode - Specifies automatic trailing newline insertion mode. Must be a value of
|
||||
* the \c auto_newline_mode enum. By default, is <tt>auto_newline_mode::insert_if_missing</tt>.
|
||||
*
|
||||
* \note Read the caution note regarding file name pattern in the <tt>sinks::file::collector::scan_for_files</tt>
|
||||
* documentation.
|
||||
@@ -512,6 +540,14 @@ public:
|
||||
*/
|
||||
BOOST_LOG_API void auto_flush(bool enable = true);
|
||||
|
||||
/*!
|
||||
* Selects whether a trailing newline should be automatically inserted after every log record. See
|
||||
* \c auto_newline_mode description for the possible modes of operation.
|
||||
*
|
||||
* \param mode The trailing newline insertion mode.
|
||||
*/
|
||||
BOOST_LOG_API void set_auto_newline_mode(auto_newline_mode mode);
|
||||
|
||||
/*!
|
||||
* \return The name of the currently open log file. If no file is open, returns an empty path.
|
||||
*/
|
||||
@@ -566,6 +602,7 @@ private:
|
||||
args[keywords::open_mode | (std::ios_base::trunc | std::ios_base::out)],
|
||||
args[keywords::rotation_size | (std::numeric_limits< uintmax_t >::max)()],
|
||||
args[keywords::time_based_rotation | time_based_rotation_predicate()],
|
||||
args[keywords::auto_newline_mode | insert_if_missing],
|
||||
args[keywords::auto_flush | false],
|
||||
args[keywords::enable_final_rotation | true]);
|
||||
}
|
||||
@@ -576,6 +613,7 @@ private:
|
||||
std::ios_base::openmode mode,
|
||||
uintmax_t rotation_size,
|
||||
time_based_rotation_predicate const& time_based_rotation,
|
||||
auto_newline_mode auto_newline,
|
||||
bool auto_flush,
|
||||
bool enable_final_rotation);
|
||||
|
||||
|
||||
@@ -44,18 +44,18 @@ namespace sinks {
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_1(n, data)\
|
||||
#define BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_1(z, n, data)\
|
||||
template< typename T0 >\
|
||||
explicit text_ipc_message_queue_backend(T0 const& arg0, typename boost::log::aux::enable_if_named_parameters< T0, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :\
|
||||
m_queue(arg0) {}
|
||||
|
||||
#define BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_N(n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
|
||||
explicit text_ipc_message_queue_backend(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg)) :\
|
||||
m_queue(BOOST_PP_ENUM_PARAMS(n, arg)) {}
|
||||
#define BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_N(z, n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS_Z(z, n, typename T) >\
|
||||
explicit text_ipc_message_queue_backend(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, const& arg)) :\
|
||||
m_queue(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) {}
|
||||
|
||||
#define BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL(z, n, data)\
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_1, BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_N)(n, data)
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_1, BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_N)(z, n, data)
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
|
||||
@@ -25,7 +25,10 @@
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/light_function.hpp>
|
||||
#include <boost/log/detail/parameter_tools.hpp>
|
||||
#include <boost/log/detail/cleanup_scope_guard.hpp>
|
||||
#include <boost/log/keywords/auto_newline_mode.hpp>
|
||||
#include <boost/log/sinks/auto_newline_mode.hpp>
|
||||
#include <boost/log/sinks/basic_sink_backend.hpp>
|
||||
#include <boost/log/utility/formatting_ostream.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
@@ -161,10 +164,24 @@ private:
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. The constructed sink backend has no file name composer and
|
||||
* thus will not write any files.
|
||||
* thus will not write any files. All other parameters are set to their defaults.
|
||||
*/
|
||||
BOOST_LOG_API text_multifile_backend();
|
||||
|
||||
/*!
|
||||
* Constructor. Creates a sink backend with the specified named parameters.
|
||||
* The following named parameters are supported:
|
||||
*
|
||||
* \li \c auto_newline_mode - Specifies automatic trailing newline insertion mode. Must be a value of
|
||||
* the \c auto_newline_mode enum. By default, is <tt>auto_newline_mode::insert_if_missing</tt>.
|
||||
*/
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(text_multifile_backend, construct)
|
||||
#else
|
||||
template< typename... ArgsT >
|
||||
explicit text_multifile_backend(ArgsT... const& args);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
@@ -181,6 +198,14 @@ public:
|
||||
set_file_name_composer_internal(composer);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Selects whether a trailing newline should be automatically inserted after every log record. See
|
||||
* \c auto_newline_mode description for the possible modes of operation.
|
||||
*
|
||||
* \param mode The trailing newline insertion mode.
|
||||
*/
|
||||
BOOST_LOG_API void set_auto_newline_mode(auto_newline_mode mode);
|
||||
|
||||
/*!
|
||||
* The method writes the message to the sink
|
||||
*/
|
||||
@@ -188,6 +213,15 @@ public:
|
||||
|
||||
private:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Constructor implementation
|
||||
template< typename ArgsT >
|
||||
void construct(ArgsT const& args)
|
||||
{
|
||||
construct(args[keywords::auto_newline_mode | insert_if_missing]);
|
||||
}
|
||||
//! Constructor implementation
|
||||
BOOST_LOG_API void construct(auto_newline_mode auto_newline);
|
||||
|
||||
//! The method sets the file name composer
|
||||
BOOST_LOG_API void set_file_name_composer_internal(file_name_composer_type const& composer);
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <ostream>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/parameter_tools.hpp>
|
||||
#include <boost/log/keywords/auto_flush.hpp>
|
||||
#include <boost/log/keywords/auto_newline_mode.hpp>
|
||||
#include <boost/log/sinks/auto_newline_mode.hpp>
|
||||
#include <boost/log/sinks/basic_sink_backend.hpp>
|
||||
#include <boost/log/sinks/frontend_requirements.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
@@ -71,6 +75,23 @@ public:
|
||||
* Constructor. No streams attached to the constructed backend, auto flush feature disabled.
|
||||
*/
|
||||
BOOST_LOG_API basic_text_ostream_backend();
|
||||
|
||||
/*!
|
||||
* Constructor. Creates a sink backend with the specified named parameters.
|
||||
* The following named parameters are supported:
|
||||
*
|
||||
* \li \c auto_flush - Specifies a flag, whether or not to automatically flush the attached streams after each
|
||||
* written log record. By default, is \c false.
|
||||
* \li \c auto_newline_mode - Specifies automatic trailing newline insertion mode. Must be a value of
|
||||
* the \c auto_newline_mode enum. By default, is <tt>auto_newline_mode::insert_if_missing</tt>.
|
||||
*/
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(basic_text_ostream_backend, construct)
|
||||
#else
|
||||
template< typename... ArgsT >
|
||||
explicit basic_text_ostream_backend(ArgsT... const& args);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
@@ -91,19 +112,43 @@ public:
|
||||
BOOST_LOG_API void remove_stream(shared_ptr< stream_type > const& strm);
|
||||
|
||||
/*!
|
||||
* Sets the flag to automatically flush buffers of all attached streams after each log record
|
||||
* Sets the flag to automatically flush buffers of all attached streams after each log record.
|
||||
*
|
||||
* \param enable The flag indicates whether the automatic buffer flush should be performed.
|
||||
*/
|
||||
BOOST_LOG_API void auto_flush(bool f = true);
|
||||
BOOST_LOG_API void auto_flush(bool enable = true);
|
||||
|
||||
/*!
|
||||
* The method writes the message to the sink
|
||||
* Selects whether a trailing newline should be automatically inserted after every log record. See
|
||||
* \c auto_newline_mode description for the possible modes of operation.
|
||||
*
|
||||
* \param mode The trailing newline insertion mode.
|
||||
*/
|
||||
BOOST_LOG_API void set_auto_newline_mode(auto_newline_mode mode);
|
||||
|
||||
/*!
|
||||
* The method writes the message to the sink.
|
||||
*/
|
||||
BOOST_LOG_API void consume(record_view const& rec, string_type const& formatted_message);
|
||||
|
||||
/*!
|
||||
* The method flushes the associated streams
|
||||
* The method flushes all attached streams.
|
||||
*/
|
||||
BOOST_LOG_API void flush();
|
||||
|
||||
private:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Constructor implementation
|
||||
template< typename ArgsT >
|
||||
void construct(ArgsT const& args)
|
||||
{
|
||||
construct(
|
||||
args[keywords::auto_newline_mode | insert_if_missing],
|
||||
args[keywords::auto_flush | false]);
|
||||
}
|
||||
//! Constructor implementation
|
||||
BOOST_LOG_API void construct(auto_newline_mode auto_newline, bool auto_flush);
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
};
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
|
||||
@@ -39,20 +39,20 @@ namespace sinks {
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1(n, data)\
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1(z, n, data)\
|
||||
template< typename T0 >\
|
||||
explicit unlocked_sink(T0 const& arg0, typename boost::log::aux::enable_if_named_parameters< T0, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :\
|
||||
base_type(false),\
|
||||
m_pBackend(boost::make_shared< sink_backend_type >(arg0)) {}
|
||||
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N(n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
|
||||
explicit unlocked_sink(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg)) :\
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N(z, n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS_Z(z, n, typename T) >\
|
||||
explicit unlocked_sink(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, const& arg)) :\
|
||||
base_type(false),\
|
||||
m_pBackend(boost::make_shared< sink_backend_type >(BOOST_PP_ENUM_PARAMS(n, arg))) {}
|
||||
m_pBackend(boost::make_shared< sink_backend_type >(BOOST_PP_ENUM_PARAMS_Z(z, n, arg))) {}
|
||||
|
||||
#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL(z, n, data)\
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1, BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N)(n, data)
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_1, BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL_N)(z, n, data)
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user