Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:25

0001 /*
0002  *                 Copyright Lingxi Li 2015.
0003  *              Copyright Andrey Semashev 2016.
0004  * Distributed under the Boost Software License, Version 1.0.
0005  *    (See accompanying file LICENSE_1_0.txt or copy at
0006  *          http://www.boost.org/LICENSE_1_0.txt)
0007  */
0008 /*!
0009  * \file   text_ipc_message_queue_backend.hpp
0010  * \author Lingxi Li
0011  * \author Andrey Semashev
0012  * \date   14.10.2015
0013  *
0014  * The header contains implementation of a text interprocess message queue sink
0015  * backend along with implementation of a supporting interprocess message queue.
0016  */
0017 
0018 #ifndef BOOST_LOG_SINKS_TEXT_IPC_MESSAGE_QUEUE_BACKEND_HPP_INCLUDED_
0019 #define BOOST_LOG_SINKS_TEXT_IPC_MESSAGE_QUEUE_BACKEND_HPP_INCLUDED_
0020 
0021 #include <limits>
0022 #include <string>
0023 #include <boost/cstdint.hpp>
0024 #include <boost/move/core.hpp>
0025 #include <boost/preprocessor/control/if.hpp>
0026 #include <boost/preprocessor/comparison/equal.hpp>
0027 #include <boost/log/detail/config.hpp>
0028 #include <boost/log/detail/parameter_tools.hpp>
0029 #include <boost/log/core/record_view.hpp>
0030 #include <boost/log/sinks/basic_sink_backend.hpp>
0031 #include <boost/log/sinks/frontend_requirements.hpp>
0032 #include <boost/log/exceptions.hpp>
0033 #include <boost/log/detail/header.hpp>
0034 
0035 #ifdef BOOST_HAS_PRAGMA_ONCE
0036 #pragma once
0037 #endif
0038 
0039 namespace boost {
0040 
0041 BOOST_LOG_OPEN_NAMESPACE
0042 
0043 namespace sinks {
0044 
0045 #ifndef BOOST_LOG_DOXYGEN_PASS
0046 
0047 #define BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_1(z, n, data)\
0048     template< typename T0 >\
0049     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()) :\
0050         m_queue(arg0) {}
0051 
0052 #define BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_N(z, n, data)\
0053     template< BOOST_PP_ENUM_PARAMS_Z(z, n, typename T) >\
0054     explicit text_ipc_message_queue_backend(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, const& arg)) :\
0055         m_queue(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) {}
0056 
0057 #define BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL(z, n, data)\
0058     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)
0059 
0060 #endif // BOOST_LOG_DOXYGEN_PASS
0061 
0062 /*!
0063  * \brief An implementation of a text interprocess message queue sink backend and
0064  *        a supporting interprocess message queue.
0065  *
0066  * The sink backend sends formatted log messages to an interprocess message queue
0067  * which can be extracted by a viewer process. Methods of this class are not
0068  * thread-safe, unless otherwise specified.
0069  */
0070 template< typename QueueT >
0071 class text_ipc_message_queue_backend :
0072     public basic_formatted_sink_backend< char, concurrent_feeding >
0073 {
0074     //! Base type
0075     typedef basic_formatted_sink_backend< char, concurrent_feeding > base_type;
0076 
0077 public:
0078     //! Character type
0079     typedef base_type::char_type char_type;
0080     //! String type to be used as a message text holder
0081     typedef base_type::string_type string_type;
0082     //! Interprocess message queue type
0083     typedef QueueT queue_type;
0084 
0085 private:
0086     //! Interprocess queue
0087     queue_type m_queue;
0088 
0089 public:
0090     /*!
0091      * Default constructor. The method constructs the backend using the default-constructed
0092      * interprocess message queue. The queue may need additional setup in order to be able
0093      * to send messages.
0094      */
0095     text_ipc_message_queue_backend() BOOST_NOEXCEPT
0096     {
0097     }
0098 
0099     /*!
0100      * Initializing constructor. The method constructs the backend using the provided
0101      * interprocess message queue. The constructor moves from the provided queue.
0102      */
0103     explicit text_ipc_message_queue_backend(BOOST_RV_REF(queue_type) queue) BOOST_NOEXCEPT :
0104         m_queue(static_cast< BOOST_RV_REF(queue_type) >(queue))
0105     {
0106     }
0107 
0108     /*!
0109      * Constructor that passes arbitrary named parameters to the interprocess queue constructor.
0110      * Refer to the queue documentation for the list of supported parameters.
0111      */
0112 #ifndef BOOST_LOG_DOXYGEN_PASS
0113     BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL, ~)
0114 #else
0115     template< typename... Args >
0116     explicit text_ipc_message_queue_backend(Args&&... args);
0117 #endif
0118 
0119     /*!
0120      * The method returns a reference to the managed \c queue_type object.
0121      *
0122      * \return A reference to the managed \c queue_type object.
0123      */
0124     queue_type& message_queue() BOOST_NOEXCEPT { return m_queue; }
0125 
0126     /*!
0127      * The method returns a constant reference to the managed \c queue_type object.
0128      *
0129      * \return A constant reference to the managed \c queue_type object.
0130      */
0131     queue_type const& message_queue() const BOOST_NOEXCEPT { return m_queue; }
0132 
0133     /*!
0134      * Tests whether the object is associated with any message queue. Only when the backend has
0135      * an associated message queue, will any message be sent.
0136      *
0137      * \return \c true if the object is associated with a message queue, and \c false otherwise.
0138      */
0139     bool is_open() const BOOST_NOEXCEPT { return m_queue.is_open(); }
0140 
0141     /*!
0142      * The method writes the message to the backend. Concurrent calls to this method
0143      * are allowed. Therefore, the backend may be used with unlocked frontend. <tt>stop_local()</tt>
0144      * can be used to have a blocked <tt>consume()</tt> call return and prevent future
0145      * calls to <tt>consume()</tt> from blocking.
0146      */
0147     void consume(record_view const&, string_type const& formatted_message)
0148     {
0149         if (m_queue.is_open())
0150         {
0151             typedef typename queue_type::size_type size_type;
0152             const string_type::size_type size = formatted_message.size();
0153             if (BOOST_UNLIKELY(size > static_cast< string_type::size_type >((std::numeric_limits< size_type >::max)())))
0154                 BOOST_LOG_THROW_DESCR(limitation_error, "Message too long to send to an interprocess queue");
0155             m_queue.send(formatted_message.data(), static_cast< size_type >(size));
0156         }
0157     }
0158 };
0159 
0160 #undef BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_1
0161 #undef BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL_N
0162 #undef BOOST_LOG_IPC_BACKEND_CTOR_FORWARD_INTERNAL
0163 
0164 } // namespace sinks
0165 
0166 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0167 
0168 } // namespace boost
0169 
0170 #include <boost/log/detail/footer.hpp>
0171 
0172 #endif // BOOST_LOG_SINKS_TEXT_IPC_MESSAGE_QUEUE_BACKEND_HPP_INCLUDED_