📄 consumermanager.cpp
字号:
//%2006//////////////////////////////////////////////////////////////////////////// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation, The Open Group.// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; Symantec Corporation; The Open Group.//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions:// // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.////==============================================================================//// Author: Heather Sterling (hsterl@us.ibm.com)//// Modified By: ////%/////////////////////////////////////////////////////////////////////////////#include <Pegasus/Common/Config.h>//#include <cstdlib>//#include <dlfcn.h>#include <Pegasus/Common/System.h>#include <Pegasus/Common/FileSystem.h>#include <Pegasus/Common/Tracer.h>#include <Pegasus/Common/Logger.h>#include <Pegasus/Common/XmlReader.h>#include <Pegasus/Common/ThreadPool.h>#include <Pegasus/Common/XmlParser.h>#include <Pegasus/Common/XmlWriter.h>#include <Pegasus/Common/List.h>#include <Pegasus/Common/Mutex.h>#include "ConsumerManager.h"PEGASUS_NAMESPACE_BEGINPEGASUS_USING_STD;//ATTN: Can we just use a properties file instead?? If we only have one property, we may want to just parse it ourselves.// We may need to add more properties, however. Potential per consumer properties: unloadOk, idleTimout, retryCount, etcstatic struct OptionRow optionsTable[] =//optionname defaultvalue rqd type domain domainsize clname hlpmsg{{"location", "", false, Option::STRING, 0, 0, "location", "library name for the consumer"},};const Uint32 NUM_OPTIONS = sizeof(optionsTable) / sizeof(optionsTable[0]);//retry settingsstatic const Uint32 DEFAULT_MAX_RETRY_COUNT = 5;static const Uint32 DEFAULT_RETRY_LAPSE = 300000; //ms = 5 minutes//constant for fake property that is added to instances when serializing to track the full URLstatic const String URL_PROPERTY = "URLString";ConsumerManager::ConsumerManager(const String& consumerDir, const String& consumerConfigDir, Boolean enableConsumerUnload, Uint32 idleTimeout) : _consumerDir(consumerDir),_consumerConfigDir(consumerConfigDir),_enableConsumerUnload(enableConsumerUnload),_idleTimeout(idleTimeout),_forceShutdown(true){ PEG_METHOD_ENTER(TRC_LISTENER, "ConsumerManager::ConsumerManager"); PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Consumer library directory: " + consumerDir); PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Consumer configuration directory: " + consumerConfigDir); Tracer::trace(__FILE__,__LINE__,TRC_LISTENER,Tracer::LEVEL4, "Consumer unload enabled %d: idle timeout %d", enableConsumerUnload, idleTimeout); //ATTN: Bugzilla 3765 - Uncomment when OptionManager has a reset capability //_optionMgr.registerOptions(optionsTable, NUM_OPTIONS); struct timeval deallocateWait = {15, 0}; _thread_pool = new ThreadPool(0, "ConsumerManager", 0, 0, deallocateWait); _init(); PEG_METHOD_EXIT();}ConsumerManager::~ConsumerManager(){ PEG_METHOD_ENTER(TRC_LISTENER, "ConsumerManager::~ConsumerManager"); unloadAllConsumers(); delete _thread_pool; ConsumerTable::Iterator i = _consumers.start(); for (; i!=0; i++) { DynamicConsumer* consumer = i.value(); delete consumer; } PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Deleted all consumers"); ModuleTable::Iterator j = _modules.start(); for (;j!=0;j++) { ConsumerModule* module = j.value(); delete module; } PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Deleted all modules"); PEG_METHOD_EXIT();}void ConsumerManager::_init(){ PEG_METHOD_ENTER(TRC_LISTENER, "ConsumerManager::_init"); //check if there are any outstanding indications Array<String> files; Uint32 pos; String consumerName; if (FileSystem::getDirectoryContents(_consumerConfigDir, files)) { for (Uint32 i = 0; i < files.size(); i++) { pos = files[i].find(".dat"); if (pos != PEG_NOT_FOUND) { consumerName = files[i].subString(0, pos); try { PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Attempting to load indication for!" + consumerName + "!"); getConsumer(consumerName); } catch (...) { PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Cannot load consumer from file " + files[i]); } } } } PEG_METHOD_EXIT();}String ConsumerManager::getConsumerDir(){ return _consumerDir;}String ConsumerManager::getConsumerConfigDir(){ return _consumerConfigDir;}Boolean ConsumerManager::getEnableConsumerUnload(){ return _enableConsumerUnload;}Uint32 ConsumerManager::getIdleTimeout(){ return _idleTimeout;}/** Retrieves the library name associated with the consumer name. By default, the library name * is the same as the consumer name. However, you may specify a different library name in a consumer * configuration file. This file must be named "MyConsumer.txt" and contain the following: * location="libraryName" * * The config file is optional and is generally only needed in cases where there are strict requirements * on library naming. * * It is the responsibility of the caller to catch any exceptions thrown by this method. */String ConsumerManager::_getConsumerLibraryName(const String & consumerName){ PEG_METHOD_ENTER(TRC_LISTENER, "ConsumerManager::getConsumerLibraryName"); //default library name is consumer name String libraryName = consumerName; //check whether an alternative library name was specified in an optional consumer config file String configFile = FileSystem::getAbsolutePath((const char*)_consumerConfigDir.getCString(), String(consumerName + ".conf")); PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Looking for config file " + configFile); if (FileSystem::exists(configFile) && FileSystem::canRead(configFile)) { PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Found config file for consumer " + consumerName); try { //Bugzilla 3765 - Change this to use a member var when OptionManager has a reset option OptionManager _optionMgr; _optionMgr.registerOptions(optionsTable, NUM_OPTIONS); //comment this line out later _optionMgr.mergeFile(configFile); _optionMgr.checkRequiredOptions(); if (!_optionMgr.lookupValue("location", libraryName) || (libraryName == String::EMPTY)) { PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL2, "Warning: Using default library name since none was specified in " + configFile); libraryName = consumerName; } } catch (Exception & ex) { throw Exception(MessageLoaderParms("DynListener.ConsumerManager.INVALID_CONFIG_FILE", "Error reading $0: $1.", configFile, ex.getMessage())); } } else { PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "No config file exists for " + consumerName); } PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "The library name for " + consumerName + " is " + libraryName); PEG_METHOD_EXIT(); return libraryName;}/** Returns the DynamicConsumer for the consumerName. If it already exists, we return the one in the cache. If it * DNE, we create it and initialize it, and add it to the table. * @throws Exception if we cannot successfully create and initialize the consumer */ DynamicConsumer* ConsumerManager::getConsumer(const String& consumerName){ PEG_METHOD_ENTER(TRC_LISTENER, "ConsumerManager::getConsumer"); DynamicConsumer* consumer = 0; CIMIndicationConsumerProvider* consumerRef = 0; Boolean cached = false; Boolean entryExists = false; AutoMutex lock(_consumerTableMutex); if (_consumers.lookup(consumerName, consumer)) { //why isn't this working?? entryExists = true; if (consumer && consumer->isLoaded()) { PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL3, "Consumer exists in the cache and is already loaded: " + consumerName); cached = true; } } else { PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL3, "Consumer not found in cache, creating " + consumerName); consumer = new DynamicConsumer(consumerName); //ATTN: The above is a memory leak if _initConsumer throws an exception //need to delete it in that case } if (!cached) { _initConsumer(consumerName, consumer); if (!entryExists) { _consumers.insert(consumerName, consumer); } } consumer->updateIdleTimer(); PEG_METHOD_EXIT(); return consumer;}/** Initializes a DynamicConsumer. * Caller assumes responsibility for mutexing the operation as well as ensuring the consumer does not already exist. * @throws Exception if the consumer cannot be initialized */void ConsumerManager::_initConsumer(const String& consumerName, DynamicConsumer* consumer){ PEG_METHOD_ENTER(TRC_LISTENER, "ConsumerManager::_initConsumer"); CIMIndicationConsumerProvider* base = 0; ConsumerModule* module = 0; //lookup provider module in cache (if it exists, it returns the cached module, otherwise it creates and returns a new one) String libraryName = _getConsumerLibraryName(consumerName); module = _lookupModule(libraryName); //build library path String libraryPath = FileSystem::getAbsolutePath((const char*)_consumerDir.getCString(), FileSystem::buildLibraryFileName(libraryName)); PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Loading library: " + libraryPath); //load module try { base = module->load(consumerName, libraryPath); consumer->set(module, base); } catch (Exception& ex) { PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL2, "Error loading consumer module: " + ex.getMessage()); throw Exception(MessageLoaderParms("DynListener.ConsumerManager.CANNOT_LOAD_MODULE", "Cannot load module ($0:$1): Unknown exception.", consumerName, libraryName)); } catch (...) { throw Exception(MessageLoaderParms("DynListener.ConsumerManager.CANNOT_LOAD_MODULE", "Cannot load module ($0:$1): Unknown exception.", consumerName, libraryName)); } PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Successfully loaded consumer module " + libraryName); //initialize consumer try { PEG_TRACE_STRING(TRC_LISTENER, Tracer::LEVEL4, "Initializing Consumer " + consumerName); consumer->initialize(); //ATTN: need to change this Semaphore* semaphore = new Semaphore(0); //blocking consumer->setShutdownSemaphore(semaphore); //start the worker thread if (_thread_pool->allocate_and_awaken(consumer, _worker_routine, semaphore) != PEGASUS_THREAD_OK) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -