• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
3  * Distributed under the Boost Software License, Version 1.0.
4  *    (See accompanying file LICENSE_1_0.txt or copy at
5  *          http://www.boost.org/LICENSE_1_0.txt)
6  */
7 /*!
8  * \file   global_logger_storage.cpp
9  * \author Andrey Semashev
10  * \date   21.04.2008
11  *
12  * \brief  This header is the Boost.Log library implementation, see the library documentation
13  *         at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
14  */
15 
16 #include <boost/log/detail/config.hpp>
17 #include <map>
18 #include <string>
19 #include <boost/limits.hpp>
20 #include <boost/type_index.hpp>
21 #include <boost/log/exceptions.hpp>
22 #include <boost/log/detail/snprintf.hpp>
23 #include <boost/log/detail/singleton.hpp>
24 #include <boost/log/sources/global_logger_storage.hpp>
25 #if !defined(BOOST_LOG_NO_THREADS)
26 #include <boost/thread/mutex.hpp>
27 #include <boost/log/detail/locks.hpp>
28 #endif
29 #include <boost/log/detail/header.hpp>
30 
31 namespace boost {
32 
33 BOOST_LOG_OPEN_NAMESPACE
34 
35 namespace sources {
36 
37 namespace aux {
38 
39 BOOST_LOG_ANONYMOUS_NAMESPACE {
40 
41 //! The loggers repository singleton
42 struct loggers_repository :
43     public log::aux::lazy_singleton< loggers_repository >
44 {
45     //! Repository map type
46     typedef std::map< typeindex::type_index, shared_ptr< logger_holder_base > > loggers_map_t;
47 
48 #if !defined(BOOST_LOG_NO_THREADS)
49     //! Synchronization primitive
50     mutable mutex m_Mutex;
51 #endif
52     //! Map of logger holders
53     loggers_map_t m_Loggers;
54 };
55 
56 } // namespace
57 
58 //! Finds or creates the logger and returns its holder
59 BOOST_LOG_API shared_ptr< logger_holder_base > global_storage::get_or_init(typeindex::type_index key, initializer_t initializer)
60 {
61     typedef loggers_repository::loggers_map_t loggers_map_t;
62     loggers_repository& repo = loggers_repository::get();
63 
64     BOOST_LOG_EXPR_IF_MT(log::aux::exclusive_lock_guard< mutex > lock(repo.m_Mutex);)
65     loggers_map_t::iterator it = repo.m_Loggers.find(key);
66     if (it != repo.m_Loggers.end())
67     {
68         // There is an instance
69         return it->second;
70     }
71     else
72     {
73         // We have to create a logger instance
74         shared_ptr< logger_holder_base > inst = initializer();
75         repo.m_Loggers[key] = inst;
76         return inst;
77     }
78 }
79 
80 //! Throws the \c odr_violation exception
throw_odr_violation(typeindex::type_index tag_type,typeindex::type_index logger_type,logger_holder_base const & registered)81 BOOST_LOG_API BOOST_LOG_NORETURN void throw_odr_violation(
82     typeindex::type_index tag_type,
83     typeindex::type_index logger_type,
84     logger_holder_base const& registered)
85 {
86     char buf[std::numeric_limits< unsigned int >::digits10 + 3];
87     if (log::aux::snprintf(buf, sizeof(buf), "%u", registered.m_RegistrationLine) < 0)
88         buf[0] = '\0';
89     std::string str =
90         std::string("Could not initialize global logger with tag \"") +
91         tag_type.pretty_name() +
92         "\" and type \"" +
93         logger_type.pretty_name() +
94         "\". A logger of type \"" +
95         registered.m_LoggerType.pretty_name() +
96         "\" with the same tag has already been registered at " +
97         registered.m_RegistrationFile + ":" + buf + ".";
98 
99     BOOST_LOG_THROW_DESCR(odr_violation, str);
100 }
101 
102 } // namespace aux
103 
104 } // namespace sources
105 
106 BOOST_LOG_CLOSE_NAMESPACE // namespace log
107 
108 } // namespace boost
109 
110 #include <boost/log/detail/footer.hpp>
111