⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oopprovidermanagerrouter.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//%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.////==============================================================================////%/////////////////////////////////////////////////////////////////////////////#include <Pegasus/Common/Signal.h>#include <Pegasus/Common/Config.h>#include <Pegasus/Common/Constants.h>#include <Pegasus/Common/AutoPtr.h>#include <Pegasus/Common/ArrayInternal.h>#include <Pegasus/Common/CIMMessage.h>#include <Pegasus/Common/CIMMessageSerializer.h>#include <Pegasus/Common/CIMMessageDeserializer.h>#include <Pegasus/Common/OperationContextInternal.h>#include <Pegasus/Common/System.h>#include <Pegasus/Common/AnonymousPipe.h>#include <Pegasus/Common/Tracer.h>#include <Pegasus/Common/Logger.h>#include <Pegasus/Common/Thread.h>#include <Pegasus/Common/MessageQueueService.h>#include <Pegasus/Config/ConfigManager.h>#if defined (PEGASUS_OS_TYPE_WINDOWS)# include <windows.h>  // For CreateProcess()#elif defined (PEGASUS_OS_OS400)# include <unistd.cleinc>#elif defined (PEGASUS_OS_VMS)# include <perror.h># include <climsgdef.h># include <stdio.h># include <stdlib.h># include <string.h># include <processes.h># include <unixio.h>#else# include <unistd.h>  // For fork(), exec(), and _exit()# include <errno.h># include <sys/types.h># include <sys/resource.h># if defined(PEGASUS_HAS_SIGNALS)#  include <sys/wait.h># endif#endif#include "OOPProviderManagerRouter.h"PEGASUS_USING_STD;PEGASUS_NAMESPACE_BEGIN/////////////////////////////////////////////////////////////////////////////// OutstandingRequestTable and OutstandingRequestEntry//////////////////////////////////////////////////////////////////////////////**    An OutstandingRequestEntry represents a request message sent to a    Provider Agent for which no response has been received.  The request    sender provides the message ID and a location for the response to be    returned, and then waits on the semaphore.  When a response matching    the message ID is received, it is placed into the specified location    and the semaphore is signaled. */class OutstandingRequestEntry{public:    OutstandingRequestEntry(        String originalMessageId_,        CIMRequestMessage* requestMessage_,        CIMResponseMessage*& responseMessage_,        Semaphore* responseReady_)        : originalMessageId(originalMessageId_),          requestMessage(requestMessage_),          responseMessage(responseMessage_),          responseReady(responseReady_)    {    }    /**        A unique value is substituted as the request messageId attribute to        allow responses to be definitively correllated with requests.        The original messageId value is stored here to avoid a race condition        between the processing of a response chunk and the resetting of the        original messageId in the request message.     */    String originalMessageId;    CIMRequestMessage* requestMessage;    CIMResponseMessage*& responseMessage;    Semaphore* responseReady;};typedef HashTable<String, OutstandingRequestEntry*, EqualFunc<String>,    HashFunc<String> > OutstandingRequestTable;/////////////////////////////////////////////////////////////////////////////// ProviderAgentContainer/////////////////////////////////////////////////////////////////////////////class ProviderAgentContainer{public:    ProviderAgentContainer(        const String & moduleName,        const String & userName,        Uint16 userContext,        PEGASUS_INDICATION_CALLBACK_T indicationCallback,        PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,        PEGASUS_PROVIDERMODULEFAIL_CALLBACK_T providerModuleFailCallback,        Boolean subscriptionInitComplete);    ~ProviderAgentContainer();    Boolean isInitialized();    String getModuleName() const;    CIMResponseMessage* processMessage(CIMRequestMessage* request);    void unloadIdleProviders();private:    //    // Private methods    //    /** Unimplemented */    ProviderAgentContainer();    /** Unimplemented */    ProviderAgentContainer(const ProviderAgentContainer& pa);    /** Unimplemented */    ProviderAgentContainer& operator=(const ProviderAgentContainer& pa);    /**        Start a Provider Agent process and establish a pipe connection with it.        Note: The caller must lock the _agentMutex.     */    void _startAgentProcess();    /**        Send initialization data to the Provider Agent.        Note: The caller must lock the _agentMutex.     */    void _sendInitializationData();    /**        Initialize the ProviderAgentContainer if it is not already        initialized.  Initialization includes starting the Provider Agent        process, establishing a pipe connection with it, and starting a        thread to read response messages from the Provider Agent.        Note: The caller must lock the _agentMutex.     */    void _initialize();    /**        Uninitialize the ProviderAgentContainer if it is initialized.        The connection is closed and outstanding requests are completed        with an error result.        Note: The caller must lock the _agentMutex.        @param cleanShutdown Indicates whether the provider agent process        exited cleanly.  A value of true indicates that responses have been        sent for all requests that have been processed.  A value of false        indicates that one or more requests may have been partially processed.     */    void _uninitialize(Boolean cleanShutdown);    /**        Performs the processMessage work, but does not retry on a transient        error.     */    CIMResponseMessage* _processMessage(CIMRequestMessage* request);    /**        Read and process response messages from the Provider Agent until        the connection is closed.     */    void _processResponses();    static ThreadReturnType PEGASUS_THREAD_CDECL        _responseProcessor(void* arg);    //    // Private data    //    /**        The _agentMutex must be locked whenever writing to the Provider        Agent connection, accessing the _isInitialized flag, or changing        the Provider Agent state.     */    Mutex _agentMutex;    /**        Name of the provider module served by this Provider Agent.     */    String _moduleName;    /**        The user context in which this Provider Agent operates.     */    String _userName;    /**        User Context setting of the provider module served by this Provider        Agent.     */    Uint16 _userContext;    /**        Callback function to which all generated indications are sent for        processing.     */    PEGASUS_INDICATION_CALLBACK_T _indicationCallback;    /**        Callback function to which response chunks are sent for processing.     */    PEGASUS_RESPONSE_CHUNK_CALLBACK_T _responseChunkCallback;    /**        Callback function to be called upon detection of failure of a        provider module.     */    PEGASUS_PROVIDERMODULEFAIL_CALLBACK_T _providerModuleFailCallback;    /**        Indicates whether the Provider Agent is active.     */    Boolean _isInitialized;    /**        Pipe connection used to read responses from the Provider Agent.     */    AutoPtr<AnonymousPipe> _pipeFromAgent;    /**        Pipe connection used to write requests to the Provider Agent.     */    AutoPtr<AnonymousPipe> _pipeToAgent;#if defined(PEGASUS_HAS_SIGNALS)    /**        Process ID of the active Provider Agent.     */    pid_t _pid;#endif    /**        The _outstandingRequestTable holds an entry for each request that has        been sent to this Provider Agent for which no response has been        received.  Entries are added (by the writing thread) when a request        is sent, and are removed (by the reading thread) when the response is        received (or when it is determined that no response is forthcoming).     */    OutstandingRequestTable _outstandingRequestTable;    /**        The _outstandingRequestTableMutex must be locked whenever reading or        updating the _outstandingRequestTable.     */    Mutex _outstandingRequestTableMutex;    /**        Holds the last provider module instance sent to the Provider Agent in        a ProviderIdContainer.  Since the provider module instance rarely        changes, an optimization is used to send it only when it differs from        the last provider module instance sent.     */    CIMInstance _providerModuleCache;    /**        The number of Provider Agent processes that are currently initialized        (active).    */    static Uint32 _numProviderProcesses;    /**        The _numProviderProcessesMutex must be locked whenever reading or        updating the _numProviderProcesses count.    */    static Mutex _numProviderProcessesMutex;    /**        The maximum number of Provider Agent processes that may be initialized        (active) at one time.    */    static Uint32 _maxProviderProcesses;    /**        A value indicating that a request message has not been processed.        A CIMResponseMessage pointer with this value indicates that the        corresponding CIMRequestMessage has not been processed.  This is        used to indicate that a provider agent exited without starting to        process the request, and that the request should be retried.     */    static CIMResponseMessage* _REQUEST_NOT_PROCESSED;    /**        Indicates whether the Indication Service has completed initialization.        For more information, please see the description of the        ProviderManagerRouter::_subscriptionInitComplete member variable.     */    Boolean _subscriptionInitComplete;};Uint32 ProviderAgentContainer::_numProviderProcesses = 0;Mutex ProviderAgentContainer::_numProviderProcessesMutex;Uint32 ProviderAgentContainer::_maxProviderProcesses = PEG_NOT_FOUND;// Set this to a value that no valid CIMResponseMessage* will have.CIMResponseMessage* ProviderAgentContainer::_REQUEST_NOT_PROCESSED =    reinterpret_cast<CIMResponseMessage*>(&_REQUEST_NOT_PROCESSED);ProviderAgentContainer::ProviderAgentContainer(    const String & moduleName,    const String & userName,    Uint16 userContext,    PEGASUS_INDICATION_CALLBACK_T indicationCallback,    PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,    PEGASUS_PROVIDERMODULEFAIL_CALLBACK_T providerModuleFailCallback,    Boolean subscriptionInitComplete)    : _moduleName(moduleName),      _userName(userName),      _userContext(userContext),      _indicationCallback(indicationCallback),      _responseChunkCallback(responseChunkCallback),      _providerModuleFailCallback(providerModuleFailCallback),      _isInitialized(false),      _subscriptionInitComplete(subscriptionInitComplete){    PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,        "ProviderAgentContainer::ProviderAgentContainer");    PEG_METHOD_EXIT();}ProviderAgentContainer::~ProviderAgentContainer(){    PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,        "ProviderAgentContainer::~ProviderAgentContainer");    // Ensure the destructor does not throw an exception    try    {        if (isInitialized())        {            // Stop the responseProcessor thread by closing its connection            _pipeFromAgent->closeReadHandle();            // Wait for the responseProcessor thread to exit            while (isInitialized())            {                Threads::yield();            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -