diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/log/message_initializer.cc | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/lib/log/message_initializer.cc b/src/lib/log/message_initializer.cc new file mode 100644 index 0000000..a7c85ed --- /dev/null +++ b/src/lib/log/message_initializer.cc @@ -0,0 +1,137 @@ +// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <log/message_dictionary.h> +#include <log/message_initializer.h> +#include <algorithm> +#include <cassert> +#include <cstdlib> + + +namespace { + +using namespace isc::log; + +/// @brief Returns the shared pointer to the list of pointers to the +/// log messages defined. +/// +/// The returned pointer must be held in the \c MessageInitializer object +/// throughout its lifetime to make sure that the object doesn't outlive +/// the list and may still access it in the destructor. The returned +/// pointer is shared between all \c MessageInitializer instances. +LoggerValuesListPtr +getNonConstLoggerValues() { + static LoggerValuesListPtr logger_values(new LoggerValuesList()); + return (logger_values); +} + +/// @brief Returns the pointer to the list of message duplicates. +/// +/// The returned pointer must be held in the \c MessageInitializer object +/// throughout its lifetime to make sure that the object doesn't outlive +/// the list and may still access it in the destructor. The returned +/// pointer is shared between all \c MessageInitializer instances. +LoggerDuplicatesListPtr +getNonConstDuplicates() { + static LoggerDuplicatesListPtr duplicates(new LoggerDuplicatesList()); + return (duplicates); +} +} // end unnamed namespace + + +namespace isc { +namespace log { + +MessageInitializer::MessageInitializer(const char* values[]) + : values_(values), + global_dictionary_(MessageDictionary::globalDictionary()), + global_logger_values_(getNonConstLoggerValues()), + global_logger_duplicates_(getNonConstDuplicates()) { + global_logger_values_->push_back(values); +} + +MessageInitializer::~MessageInitializer() { + // Search for the pointer to pending messages belonging to our instance. + LoggerValuesList::iterator my_messages = std::find(global_logger_values_->begin(), + global_logger_values_->end(), + values_); + bool pending = (my_messages != global_logger_values_->end()); + // Our messages are still pending, so let's remove them from the list + // of pending messages. + if (pending) { + global_logger_values_->erase(my_messages); + + } else { + // Our messages are not pending, so they might have been loaded to + // the dictionary and/or duplicates. + int i = 0; + while (values_[i]) { + // Check if the unloaded message is registered as duplicate. If it is, + // remove it from the duplicates list. + LoggerDuplicatesList::iterator dup = + std::find(global_logger_duplicates_->begin(), + global_logger_duplicates_->end(), + values_[i]); + if (dup != global_logger_duplicates_->end()) { + global_logger_duplicates_->erase(dup); + + } else { + global_dictionary_->erase(values_[i], values_[i + 1]); + } + i += 2; + } + } +} + +// Return the number of arrays registered but not yet loaded. + +size_t +MessageInitializer::getPendingCount() { + return (getNonConstLoggerValues()->size()); +} + +// Load the messages in the arrays registered in the logger_values array +// into the global dictionary. + +void +MessageInitializer::loadDictionary(bool ignore_duplicates) { + const MessageDictionaryPtr& global = MessageDictionary::globalDictionary(); + const LoggerValuesListPtr& logger_values = getNonConstLoggerValues(); + + for (LoggerValuesList::const_iterator values = logger_values->begin(); + values != logger_values->end(); ++values) { + std::vector<std::string> repeats = global->load(*values); + + // Append the IDs in the list just loaded (the "repeats") to the + // global list of duplicate IDs. + if (!ignore_duplicates && !repeats.empty()) { + const LoggerDuplicatesListPtr& duplicates = getNonConstDuplicates(); + duplicates->insert(duplicates->end(), repeats.begin(), repeats.end()); + } + } + + // ... and mark that the messages have been loaded. (This avoids a lot + // of "duplicate message ID" messages in some of the unit tests where the + // logging initialization code may be called multiple times.) + logger_values->clear(); +} + +// Return reference to duplicates vector +const std::list<std::string>& +MessageInitializer::getDuplicates() { + return (*getNonConstDuplicates()); +} + +// Clear the duplicates vector +void +MessageInitializer::clearDuplicates() { + getNonConstDuplicates()->clear(); +} + +} // namespace log +} // namespace isc |