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/core/snprintf.hpp> |
22 | #include <boost/log/exceptions.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(x: 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 |
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 | std::string str("Could not initialize global logger with tag \"" ); |
87 | str.append(str: tag_type.pretty_name()); |
88 | str.append(s: "\" and type \"" ); |
89 | str.append(str: logger_type.pretty_name()); |
90 | str.append(s: "\". A logger of type \"" ); |
91 | str.append(str: registered.m_LoggerType.pretty_name()); |
92 | str.append(s: "\" with the same tag has already been registered at " ); |
93 | str.append(s: registered.m_RegistrationFile); |
94 | |
95 | char buf[std::numeric_limits< unsigned int >::digits10 + 3]; |
96 | int res = boost::core::snprintf(s: buf, maxlen: sizeof(buf), format: "%u" , registered.m_RegistrationLine); |
97 | if (BOOST_LIKELY(res > 0)) |
98 | { |
99 | if (BOOST_UNLIKELY(static_cast< unsigned int >(res) >= sizeof(buf))) |
100 | res = sizeof(buf) - 1u; |
101 | |
102 | str.push_back(c: ':'); |
103 | str.append(s: buf, n: res); |
104 | } |
105 | |
106 | str.push_back(c: '.'); |
107 | |
108 | BOOST_LOG_THROW_DESCR(odr_violation, str); |
109 | } |
110 | |
111 | } // namespace aux |
112 | |
113 | } // namespace sources |
114 | |
115 | BOOST_LOG_CLOSE_NAMESPACE // namespace log |
116 | |
117 | } // namespace boost |
118 | |
119 | #include <boost/log/detail/footer.hpp> |
120 | |