Branch data Line data Source code
1 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #include <cassert>
16 : : #include <cstdlib>
17 : : #include <log/message_dictionary.h>
18 : : #include <log/message_initializer.h>
19 : :
20 : :
21 : : // As explained in the header file, initialization of the message dictionary
22 : : // is a two-stage process:
23 : : // 1) In the MessageInitializer constructor, a pointer to the array of
24 : : // messages is stored in a pre-defined array. Since the MessageInitializers
25 : : // are declared statically outside a program unit, this takes place before
26 : : // main() is called. As no heap storage is allocated in this process, we
27 : : // should avoid the static initialization fiasco in cases where
28 : : // initialization of system libraries is also carried out at the same time.
29 : : // 2) After main() starts executing, loadDictionary() is called.
30 : : //
31 : : //
32 : :
33 : : namespace {
34 : :
35 : : // Declare the array of pointers to value arrays.
36 : : const char** logger_values[isc::log::MessageInitializer::MAX_MESSAGE_ARRAYS];
37 : :
38 : : // Declare the index used to access the array. As this needs to be initialized
39 : : // at first used, it is accessed it via a function.
40 : : size_t& getIndex() {
41 : : static size_t index = 0;
42 : : return (index);
43 : : }
44 : :
45 : : }
46 : :
47 : :
48 : : namespace isc {
49 : : namespace log {
50 : :
51 : : // Constructor. Add the pointer to the message array to the global array.
52 : : // This method will trigger an assertion failure if the array overflows.
53 : :
54 : 890 : MessageInitializer::MessageInitializer(const char* values[]) {
55 [ - + ]: 890 : assert(getIndex() < MAX_MESSAGE_ARRAYS);
56 : 890 : logger_values[getIndex()++] = values;
57 : 890 : }
58 : :
59 : : // Return the number of arrays registered but not yet loaded.
60 : :
61 : : size_t
62 : 3 : MessageInitializer::getPendingCount() {
63 : 3 : return (getIndex());
64 : : }
65 : :
66 : : // Load the messages in the arrays registered in the logger_values array
67 : : // into the global dictionary.
68 : :
69 : : void
70 : 121 : MessageInitializer::loadDictionary() {
71 : 121 : MessageDictionary& global = MessageDictionary::globalDictionary();
72 : :
73 [ + + ]: 565 : for (size_t i = 0; i < getIndex(); ++i) {
74 : 888 : std::vector<std::string> repeats = global.load(logger_values[i]);
75 : :
76 : : // Append the IDs in the list just loaded (the "repeats") to the
77 : : // global list of duplicate IDs.
78 [ + + ]: 444 : if (!repeats.empty()) {
79 [ + - ]: 1 : std::vector<std::string>& duplicates = getDuplicates();
80 : : duplicates.insert(duplicates.end(), repeats.begin(),
81 : : repeats.end());
82 : : }
83 : : }
84 : :
85 : : // ... and mark that the messages have been loaded. (This avoids a lot
86 : : // of "duplicate message ID" messages in some of the unit tests where the
87 : : // logging initialization code may be called multiple times.)
88 : 121 : getIndex() = 0;
89 : 121 : }
90 : :
91 : : // Return reference to duplicate array
92 : :
93 : 122 : std::vector<std::string>& MessageInitializer::getDuplicates() {
94 [ + + ][ + - ]: 122 : static std::vector<std::string> duplicates;
95 : 122 : return (duplicates);
96 : : }
97 : :
98 : : } // namespace log
99 : 893 : } // namespace isc
|