Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file sync_frontend.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 14.07.2009 Chris@16: * Chris@16: * The header contains implementation of synchronous sink frontend. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_SINKS_SYNC_FRONTEND_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_SINKS_SYNC_FRONTEND_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #if defined(BOOST_LOG_NO_THREADS) Chris@16: #error Boost.Log: Synchronous sink frontend is only supported in multithreaded environment Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace sinks { Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: #define BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL(z, n, data)\ Chris@16: template< BOOST_PP_ENUM_PARAMS(n, typename T) >\ Chris@16: explicit synchronous_sink(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg)) :\ Chris@16: base_type(false),\ Chris@16: m_pBackend(boost::make_shared< sink_backend_type >(BOOST_PP_ENUM_PARAMS(n, arg))) {} Chris@16: Chris@16: #endif // BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: /*! Chris@16: * \brief Synchronous logging sink frontend Chris@16: * Chris@16: * The sink frontend serializes threads before passing logging records to the backend Chris@16: */ Chris@16: template< typename SinkBackendT > Chris@16: class synchronous_sink : Chris@101: public aux::make_sink_frontend_base< SinkBackendT >::type Chris@16: { Chris@16: typedef typename aux::make_sink_frontend_base< SinkBackendT >::type base_type; Chris@16: Chris@16: private: Chris@16: //! Synchronization mutex type Chris@101: typedef boost::recursive_mutex backend_mutex_type; Chris@16: Chris@16: public: Chris@16: //! Sink implementation type Chris@16: typedef SinkBackendT sink_backend_type; Chris@16: //! \cond Chris@16: 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"); Chris@16: //! \endcond Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: //! A pointer type that locks the backend until it's destroyed Chris@101: typedef boost::log::aux::locking_ptr< sink_backend_type, backend_mutex_type > locked_backend_ptr; Chris@16: Chris@16: #else // BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: //! A pointer type that locks the backend until it's destroyed Chris@16: typedef implementation_defined locked_backend_ptr; Chris@16: Chris@16: #endif // BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: private: Chris@16: //! Synchronization mutex Chris@16: backend_mutex_type m_BackendMutex; Chris@16: //! Pointer to the backend Chris@16: const shared_ptr< sink_backend_type > m_pBackend; Chris@16: Chris@16: public: Chris@16: /*! Chris@16: * Default constructor. Constructs the sink backend instance. Chris@16: * Requires the backend to be default-constructible. Chris@16: */ Chris@16: synchronous_sink() : Chris@16: base_type(false), Chris@16: m_pBackend(boost::make_shared< sink_backend_type >()) Chris@16: { Chris@16: } Chris@16: /*! Chris@16: * Constructor attaches user-constructed backend instance Chris@16: * Chris@16: * \param backend Pointer to the backend instance Chris@16: * Chris@16: * \pre \a backend is not \c NULL. Chris@16: */ Chris@16: explicit synchronous_sink(shared_ptr< sink_backend_type > const& backend) : Chris@16: base_type(false), Chris@16: m_pBackend(backend) Chris@16: { Chris@16: } Chris@16: Chris@16: // Constructors that pass arbitrary parameters to the backend constructor Chris@16: BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL, ~) Chris@16: Chris@16: /*! Chris@16: * Locking accessor to the attached backend Chris@16: */ Chris@16: locked_backend_ptr locked_backend() Chris@16: { Chris@101: return locked_backend_ptr(m_pBackend, m_BackendMutex); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Passes the log record to the backend Chris@16: */ Chris@16: void consume(record_view const& rec) Chris@16: { Chris@16: base_type::feed_record(rec, m_BackendMutex, *m_pBackend); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The method attempts to pass logging record to the backend Chris@16: */ Chris@16: bool try_consume(record_view const& rec) Chris@16: { Chris@16: return base_type::try_feed_record(rec, m_BackendMutex, *m_pBackend); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The method performs flushing of any internal buffers that may hold log records. The method Chris@16: * may take considerable time to complete and may block both the calling thread and threads Chris@16: * attempting to put new records into the sink while this call is in progress. Chris@16: */ Chris@16: void flush() Chris@16: { Chris@16: base_type::flush_backend(m_BackendMutex, *m_pBackend); Chris@16: } Chris@16: }; Chris@16: Chris@16: #undef BOOST_LOG_SINK_CTOR_FORWARD_INTERNAL Chris@16: Chris@16: } // namespace sinks Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_SINKS_SYNC_FRONTEND_HPP_INCLUDED_