![]() ![]() |
![]() |
File: [Pegasus] / pegasus / src / Pegasus / Server / EnumerationContext.h
(download)
Revision: 1.7, Fri Jan 23 15:02:55 2015 UTC (9 years, 5 months ago) by karl Branch: MAIN CVS Tags: RELEASE_2_14_1, RELEASE_2_14_0-RC2, RELEASE_2_14_0-RC1, RELEASE_2_14_0, RELEASE_2_14-root, RELEASE_2_14-branch, HEAD Changes since 1.6: +4 -1 lines BUG#: 10019 TITLE: Assure that saveOperations are released for pull operations DESCRIPTION: Added code to release if found in some edge cases. |
//%LICENSE//////////////////////////////////////////////////////////////// // // Licensed to The Open Group (TOG) under one or more contributor license // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with // this work for additional information regarding copyright ownership. // Each contributor licenses this file to you under the OpenPegasus Open // Source License; you may not use this file except in compliance with the // License. // // 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. // ////////////////////////////////////////////////////////////////////////// // //%//////////////////////////////////////////////////////////////////////////// #ifndef PegasusEnumerationContext_h #define PegasusEnumerationContext_h #include <Pegasus/Common/Config.h> #include <Pegasus/Common/String.h> #include <Pegasus/Common/Thread.h> #include <Pegasus/Common/AutoPtr.h> #include <Pegasus/Common/CIMName.h> #include <Pegasus/Common/HashTable.h> #include <Pegasus/Common/List.h> #include <Pegasus/Common/UintArgs.h> #include <Pegasus/Server/Linkage.h> #include <Pegasus/Common/Tracer.h> #include <Pegasus/Common/CIMInstance.h> #include <Pegasus/Common/CIMResponseData.h> #include <Pegasus/Common/CIMMessage.h> #include <Pegasus/Common/Magic.h> #include <Pegasus/Common/Condition.h> #include <Pegasus/General/Stopwatch.h> #include <Pegasus/Server/EnumerationContextTable.h> PEGASUS_NAMESPACE_BEGIN #define LOCAL_MIN(a, b) ((a < b) ? a : b) /****************************************************************************** ** ** Class that caches each outstanding enumeration sequence. Contains ** the parameters and current status of existing enumerations ** that the server is processing. Enumerations are those ** sequences of operations starting with an Open... operation ** and proceeding through Pull... and possible close Enumeration ** operations. The enumerationContext is the glue information ** that ties the sequence of operations together. This struct ** defines the information that is maintained througout the ** life of the sequence. ** This structure also contains the queue of CIMOperationData objects ** that is fed from provider returns and accessed by the operation requests ** ******************************************************************************/ /* Keep total and average statistics on a 32bit integer. Used by enumeration to keep statistics on info in the enumeration. */ class PEGASUS_SERVER_LINKAGE Uint32Stats { public: Uint32Stats(); void reset(); // Add an entry to the statistics void add(Uint32 newInfo); // get the various pieces of intformation. Uint32 getHighWaterMark(); Uint32 getAverage(); Uint32 getCounter(); private: Uint32 _highWaterMark; Uint32 _counter; Uint32 _average; Uint64 _total; bool _overflow; }; /* Controls the EnumerationContext for pull operations. An instance of this class is the controller for the sequence of operations representing a pull sequence from open to completion. This instance provides the tools for maintaining interoperation information including: - the cache of objects to be returned as received from providers, - request information that is used by pull and close operations (timers, open request parameters, etc.), - and the state of the pull operation sequence. The key variables are: - client state(clientClosed) - whether the client is open or has been closed - providersComplete - Set true when last provider response received. - The responseData cache where responses are stored when received from providers. - contextID - The name for this context which is the client and EnumerationContextTable identification for the sequence. - Processing which is the active.inactive state where the context is active any time it is processing a client response - interoperationTimer - set non-zero with a timeout value when the processing state is inactive. */ class EnumerationContextTable; class PEGASUS_SERVER_LINKAGE EnumerationContext { public: /** Construct a single instance of Enumeration Context. This is to be used only from the EnumerationContextTable CreateContext function. @param contextId String identifier for this context. These must be unique. @param nameSpace CIMNamespaceName for this operation and therefore or this enumeration sequence. @param operationTimeoutSec - Number of seconds for the interoperation timeout for this pull sequence. Set with the open and used by the startTimer to set the timeout value between operations @param continueOnError - Boolean Flag from open request @param interoperationTimeout - microsecond timer that defines the next timeout. If zero,there is no timeout in process @param pullRequestType MessageType for all pull requests for this sequence @param contentType ResponseDataContent Type used to define the responseData cache for this context. */ EnumerationContext(const String& contextId, const CIMNamespaceName& nameSpace, Uint32 interOperationTimeoutValue, Boolean continueOnError, MessageType pullRequestType, CIMResponseData::ResponseDataContent contentType); ~EnumerationContext(); /** Get the ContextId of this enumeration context. The ContextId is the key to access the context entry in the enumeration context table. @return String containing the contextId. */ String& getContextId(); /** Set the request properties that must be moved to subsequent pull operations. */ void setRequestProperties( const Boolean includeClassOrigin, const CIMPropertyList& propertyList); /** Start the interOperation timer for this context. Uses the * interoperation timeout value as basis for setting timeout * // KS_TODO Should these be private?? start and stop timer */ void startTimer(); /* Start timer with the defined timeout*/ void startTimer(Uint64 timeoutUsec); /** Stop the interOperation timer for this context */ void stopTimer(); /** Test if this context timed out given the current time @param currentTime @return true if interoperation timer timed out */ bool isTimedOut(Uint64 currentTime); /** Test if this context timed out. Gets current time and tests against the timeout in the enumeration context entry @return true if interoperation timer timed out */ bool isTimedOut(); // diagnostic tests magic number in context to see if context valid bool valid() const; /** Test if client is closed for this enumeration. @return bool true if closed */ bool isClientClosed(); /** Test if this enumeration context has received an error response from providers, etc. @return true if errors received and not processed. */ bool isErrorState(); /**Set the error state flag and set the current cimException into the context object. This indicates that an exception was received side. @param cimException */ void setErrorState(CIMException cimException); /** Test the Message type for the open message saved in the context against the type parameter. This provides a test that insures that Pull message types match the open type. Ex. PullPaths can only be used with OpenPath contexts @param type MessageType for (for pull operation) @return Returns true if type match is correct. Returns false if not correct type. */ bool isValidPullRequestType(MessageType type) const; /** Test context to determine if it is active (i.e an operation is in process in the CIMOperationRequestDispatcher. */ bool isProcessing(); /**Put the CIMResponseData from the response message into the enumerationContext cache and if providersComplete is true, set the enumeration state to providersComplete. This function signals the getCache function conditional variable. This function may also wait if the cache is full. @param response CIMResponseMessage containing CIMResponseData to be inserted into the cache. @param providersComplete bool indicating that this is the last response from providers. @return true if data set into cache, false if enumeration closed this is last response from providers. */ bool putCache(CIMResponseMessage*& response, Boolean providersComplete); /** Wait for the cache to drop below defined size before responding to the provider. */ void waitCacheSize(); /**Get up to the number of objects defined by count from the CIMResponseData cache in the enumerationContext into the rtn CIMResponseData object. This function waits for a number of possible events as defined below and returns only when one of these events is true. This function also executes a ProviderLimitCondition signal before returning to tell the ProviderLimit condition variable that the size of the cache may have changed. @param count Uint32 count of max number of objects to return @param rtnData CIMResponseData containing the objects returned. Count of objects le count argument @return true if data acquired from cache. False if error from providers encountered */ bool getCache(Uint32 count, CIMResponseData& rtnData); /** Test cache to see if there are responses that could be used for an immediate response. Returns immediatly with true or false indicating that a response should be issued. The algorithm for the response is if request is for zero objects return true If requiresAll return true if cache has enough objects for response (ge count) || the error flag is set || the providersComplete flag is set else return true if Cache has some objects int (do not return zero objects) || the error flag is set || the providersComplete flag is set @param count Uint32 count of objects that the requests set as max number for response @param return parameter indicating that the errorFlag is set for this enumeration. @return True if passes tests for something to send or error flag set. */ bool testCacheForResponses(Uint32 operationMaxObjectCount, Boolean requiresAll); /* Setup the request and response information for a response to be issued later as part of putting provider info into the cache. This saves the request, response, and count information and starts the timer so that the delayed response will be issued after a defined time if there are no provider events @param request - The CIMOperationRequestMessage for the response that will be issued later. This could be either a pull or open response @param response - The CIMOpenOrPullResponseMessage that will be issued at a later time. Required by the function that issues the response. @param operationMaxObjecCount Uint32 that defines the maximum number of objects to be returned. */ void setupDelayedResponse(CIMOperationRequestMessage* request, CIMOpenOrPullResponseDataMessage* response, Uint32 operationMaxObjectCount); /** Returns count of objects in the EnumerationContext CIMResponseData cache. @return Uint32 count of objects currently in the cache */ Uint32 responseCacheSize(); /** Set the ProvidersComplete state. This should be set from provider responses when all responses processed. */ void setProvidersComplete(); /** Closed the client side of the EnumerationContext. From this point on, any client side requests should be rejected. Note that the providers may still be delivering CIMResponseData to the enumerationContextQueue. The CIMOperationRequestDispatcher uses the closed state to refuse pull/close operations. Once the EnumerationContext is closed, it may be removed from the enumeration context table (normally this happens when closed and providersComplete are set). */ void setClientClosed(); /** Sets the active state (i.e. Request being processed). Setting processing = true stops the interOperation timer. Otherwise the interoperation timer is started @param state bool defines whether to set processing or !processing. Processing means request being processed. */ void setProcessingState(bool state); const char* processingState(); /** Test if the provider processing is complete. @return true if provider processing is complete. */ bool providersComplete() const ; /** Called by the Dispatcher Client operation when the processing of a Request is complete, this function sets the next state for the operation, either back to wait for the next operation or complete. @param errorFound bool indicating that an error was encountered which, if continueOnError = false, forces the operation to be closed and the true response returned. @return Boolean true if the enumeration is complete. */ bool setNextEnumerationState(bool errorFound); /** Increment the count of the number of pull operations executed for this context. This method also controls the counting of operations with zero length through the input parameter. The zero length counter is reset for each call with the input parameter != zero so that this function counts total operations and also counts consecutive maxObjectCount zero length requests. @param isZeroLength bool indicating if this operation is a request for zero objects which is used to count consecutive zero length pull operations. @return true if the count of consecutive zero length pull operations exceeds a predefined maximum. */ bool incAndTestPullCounters(bool isZeroLength); /** Diagnostic to display the current context into the trace file KS_TODO eliminate or compile in debug mode only */ void trace(); // // EnumeratonContext Data // // Exception placed here in case of error. This is set by the operation // aggregate with any CIMException recieved from providers. Note that // Only one is allowed. // NO multiple errors until we get continueOnError // or really get way to return multiple errors. CIMException _cimException; // This mutex locks the entire Enumeration context for some // critical sections. the following function control this // mutex void lockContext(); void unlockContext(); bool tryLockContext(); Mutex _contextLock; /* Increment count of requests processed for this enumeration */ void incrementRequestCount(); void setContinueOnError(bool x); // get the namespace stored during the consruction CIMNamespaceName& getNamespace(); // Parameters for requests saved for future send. // CIMOperationRequestMessage* _savedRequest; CIMOpenOrPullResponseDataMessage* _savedResponse; Uint32 _savedOperationMaxObjectCount; // Pointer to Enumeration Table. Set during Create of enumeration // context EnumerationContextTable* _enumerationContextTable; /** Increment and return the zeroLenObjectResponseCounter which is a counter of the number of zero-len responses sent to the client consecetivily. The counter is cleared each time a response is recevied from a provider */ Uint32 incConsecutiveZeroLenObjectResponseCounter(); void clearConsecutiveZeroLenObjectResponseCounter(); private: // Default constructor not used EnumerationContext(); // hide assignment and copy constructor EnumerationContext(const EnumerationContext& x); EnumerationContext& operator=(const EnumerationContext&); friend class EnumerationContextTable; // Name(Id) of this EnumerationContext. String _contextId; // Namespace for this pull sequence. Set by open and used by // pull and close. CIMNamespaceName _nameSpace; // Interoperation timeout value in seconds. From open request operation // parameters. Uint32 _operationTimeoutSec; // ContinueOnError request flag.Set by open... Boolean _continueOnError; // Timeout absolute time value microseconds) for operation timeout. // 0 indicates timer not active. Used to time both interoperation // timeouts (not processing) and timeouts when enumerationContext is // active (There is a response waiting). Uint64 _operationTimerUsec; // Request Type for pull operations for this pull sequence. // Set by open. All pulls must match this type. MessageType _pullRequestType; // Status flags. // Set true when context closed from client side bool _clientClosed; // Set to true when input from providers complete. The context // cannot be removed while this is false bool _providersComplete; // set true when CIMServer is processing a request within the // enumeration context bool _processing; // Set true when error received from Providers. bool _error; // Object cache for this context. All pull responses feed their // CIMResponseData into this cache using putCache(..) and all // Open and Pull responses get data from the cache using getCache() // Simultaneous access to the cache is controlled with _responseCacheMutex // mutex. Mutex _responseCacheMutex; CIMResponseData _responseCache; // Condition variable and mutex for the provider wait // condition. This is a hold on returns from putcache when cache // reaches a defined limit that is cleared when the cache level drops // to below the defined level Condition _providerWaitCondition; Mutex _providerWaitConditionMutex; // Signal the condition variable that it should test the // providerWaitCondition condition variable. void signalProviderWaitCondition(); // Statistics for waiting. Total for this context and max for wait Uint64 _totalWaitTimeUsec; Uint64 _maxWaitTimeUsec; // Count Of pull operations executed in this context. Used for statistics Uint32 _pullOperationCounter; // Counter of consecutive requests with maxObjectCount == 0. Used to limit // client stalling by executing excessive number of zero return pull // operations. Uint32 _consecutiveZeroLenMaxObjectRequestCounter; // Counter of consecutive zero length client responses sent by the // dispatcher. Used to limit condition where providers never close // When this reaches a defined limit, a message is sent to the // OOPProviderAgent to close out the defined enumerationContext and // eventually the enumeration Context is just closed as a error. Uint32 _consecutiveZeroLenObjectResponseCounter; // Maximum number of objects that can be placed in the response Cache // before blocking providers. Uint32 _responseCacheMaximumSize; // number of requests for this EnumerationContext. Uint32 _requestCount; // Count of Objects actually returned Uint32 _responseObjectsCount; // Accumulation of count of request maxObjectCounts Uint32 _requestedResponseObjectsCount; // Counts all zero length responses sent to Client. This is // for statistics. This is, in effect the number of times during // this enumeation that the providers responded so late that we // sent a zero response. This is an indicator of provider overload, // or a provider somewhere that is responding very slowly. The timers // are such that there should be at least one response from a provider // about each 15 seconds which is the current timer for this timeout. Uint32 _totalZeroLenObjectResponseCounter; // Enumeration startTime in microseconds Uint64 _startTimeUsec; // Max number of objects in the cache. Uint32 _cacheHighWaterMark; Magic<0x57D11474> _magic; }; /****************************************************** Inline functions ******************************************************/ inline CIMNamespaceName& EnumerationContext::getNamespace() { return _nameSpace; } inline String& EnumerationContext::getContextId() { return _contextId; } inline void EnumerationContext::incrementRequestCount() { _requestCount++; } inline bool EnumerationContext::isProcessing() { return _processing; } inline bool EnumerationContext::isClientClosed() { return _clientClosed; } inline bool EnumerationContext::isErrorState() { return _error; } /* Test the current pull message against the type set on the create context. they must match */ inline bool EnumerationContext::isValidPullRequestType( MessageType type) const { return(type == _pullRequestType); } inline bool EnumerationContext::providersComplete() const { return _providersComplete; } inline Uint32 EnumerationContext::responseCacheSize() { return _responseCache.size(); } inline void EnumerationContext::lockContext() { _contextLock.lock(); } inline bool EnumerationContext::tryLockContext() { return _contextLock.try_lock(); } inline void EnumerationContext::unlockContext() { _contextLock.unlock(); } inline void EnumerationContext::setContinueOnError(Boolean x) { _continueOnError = x; } // Increment both the consecutive and total counters and return the value // of the consecutive counter. inline Uint32 EnumerationContext::incConsecutiveZeroLenObjectResponseCounter() { _totalZeroLenObjectResponseCounter++; return ++_consecutiveZeroLenObjectResponseCounter; } inline void EnumerationContext::clearConsecutiveZeroLenObjectResponseCounter() { _consecutiveZeroLenObjectResponseCounter = 0; } PEGASUS_NAMESPACE_END #endif /* PegasusEnumerationContext_h */
No CVS admin address has been configured |
Powered by ViewCVS 0.9.2 |