diff options
Diffstat (limited to 'boost/log/sinks/sync_frontend.hpp')
-rw-r--r-- | boost/log/sinks/sync_frontend.hpp | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/boost/log/sinks/sync_frontend.hpp b/boost/log/sinks/sync_frontend.hpp new file mode 100644 index 0000000000..146cc9dc44 --- /dev/null +++ b/boost/log/sinks/sync_frontend.hpp @@ -0,0 +1,166 @@ +/* + * Copyright Andrey Semashev 2007 - 2014. + * 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 sync_frontend.hpp + * \author Andrey Semashev + * \date 14.07.2009 + * + * The header contains implementation of synchronous sink frontend. + */ + +#ifndef BOOST_LOG_SINKS_SYNC_FRONTEND_HPP_INCLUDED_ +#define BOOST_LOG_SINKS_SYNC_FRONTEND_HPP_INCLUDED_ + +#include <boost/log/detail/config.hpp> + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_LOG_NO_THREADS) +#error Boost.Log: Synchronous sink frontend is only supported in multithreaded environment +#endif + +#include <boost/static_assert.hpp> +#include <boost/smart_ptr/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared_object.hpp> +#include <boost/thread/recursive_mutex.hpp> +#include <boost/log/detail/locking_ptr.hpp> +#include <boost/log/detail/parameter_tools.hpp> +#include <boost/log/core/record_view.hpp> +#include <boost/log/sinks/basic_sink_frontend.hpp> +#include <boost/log/sinks/frontend_requirements.hpp> +#include <boost/log/detail/header.hpp> + +namespace boost { + +BOOST_LOG_OPEN_NAMESPACE + +namespace sinks { + +#ifndef BOOST_LOG_DOXYGEN_PASS + +#define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL(z, n, data)\ + template< BOOST_PP_ENUM_PARAMS(n, typename T) >\ + explicit synchronous_sink(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg)) :\ + base_type(false),\ + m_pBackend(boost::make_shared< sink_backend_type >(BOOST_PP_ENUM_PARAMS(n, arg))) {} + +#endif // BOOST_LOG_DOXYGEN_PASS + +/*! + * \brief Synchronous logging sink frontend + * + * The sink frontend serializes threads before passing logging records to the backend + */ +template< typename SinkBackendT > +class synchronous_sink : + public aux::make_sink_frontend_base< SinkBackendT >::type +{ + typedef typename aux::make_sink_frontend_base< SinkBackendT >::type base_type; + +private: + //! Synchronization mutex type + typedef boost::recursive_mutex backend_mutex_type; + +public: + //! Sink implementation type + typedef SinkBackendT sink_backend_type; + //! \cond + BOOST_STATIC_ASSERT_MSG((has_requirement< typename sink_backend_type::frontend_requirements, synchronized_feeding >::value), "Synchronous sink frontend is incompatible with the specified backend: thread synchronization requirements are not met"); + //! \endcond + +#ifndef BOOST_LOG_DOXYGEN_PASS + + //! A pointer type that locks the backend until it's destroyed + typedef boost::log::aux::locking_ptr< sink_backend_type, backend_mutex_type > locked_backend_ptr; + +#else // BOOST_LOG_DOXYGEN_PASS + + //! A pointer type that locks the backend until it's destroyed + typedef implementation_defined locked_backend_ptr; + +#endif // BOOST_LOG_DOXYGEN_PASS + +private: + //! Synchronization mutex + backend_mutex_type m_BackendMutex; + //! Pointer to the backend + const shared_ptr< sink_backend_type > m_pBackend; + +public: + /*! + * Default constructor. Constructs the sink backend instance. + * Requires the backend to be default-constructible. + */ + synchronous_sink() : + base_type(false), + m_pBackend(boost::make_shared< sink_backend_type >()) + { + } + /*! + * Constructor attaches user-constructed backend instance + * + * \param backend Pointer to the backend instance + * + * \pre \a backend is not \c NULL. + */ + explicit synchronous_sink(shared_ptr< sink_backend_type > const& backend) : + base_type(false), + m_pBackend(backend) + { + } + + // Constructors that pass arbitrary parameters to the backend constructor + BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL, ~) + + /*! + * Locking accessor to the attached backend + */ + locked_backend_ptr locked_backend() + { + return locked_backend_ptr(m_pBackend, m_BackendMutex); + } + + /*! + * Passes the log record to the backend + */ + void consume(record_view const& rec) + { + base_type::feed_record(rec, m_BackendMutex, *m_pBackend); + } + + /*! + * The method attempts to pass logging record to the backend + */ + bool try_consume(record_view const& rec) + { + return base_type::try_feed_record(rec, m_BackendMutex, *m_pBackend); + } + + /*! + * The method performs flushing of any internal buffers that may hold log records. The method + * 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() + { + base_type::flush_backend(m_BackendMutex, *m_pBackend); + } +}; + +#undef BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL + +} // namespace sinks + +BOOST_LOG_CLOSE_NAMESPACE // namespace log + +} // namespace boost + +#include <boost/log/detail/footer.hpp> + +#endif // BOOST_LOG_SINKS_SYNC_FRONTEND_HPP_INCLUDED_ |