1 karl 1.2 //%LICENSE////////////////////////////////////////////////////////////////
2 //
3 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 karl 1.2 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //////////////////////////////////////////////////////////////////////////
29 //
30 //%////////////////////////////////////////////////////////////////////////////
31
32 #include "EnumerationContext.h"
33
34 #include <Pegasus/Common/Mutex.h>
35 #include <Pegasus/Common/Time.h>
36 #include <Pegasus/Common/TimeValue.h>
37 #include <Pegasus/Common/List.h>
38 #include <Pegasus/General/Guid.h>
39 #include <Pegasus/Common/CIMResponseData.h>
40 #include <Pegasus/Common/Condition.h>
41 #include <Pegasus/Common/Tracer.h>
42 #include <Pegasus/General/Stopwatch.h>
43 karl 1.2 #include <Pegasus/Common/Thread.h>
44
45
46 PEGASUS_USING_STD;
47 PEGASUS_NAMESPACE_BEGIN
48
49 #define MAX_ZERO_PULL_OPERATIONS 1000
50
51 // When set enables the diagnostic traces in this class
52 // These should only be enabled for development or special testing
53 #define ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
54
55
56 // Create a new context. This is called only from the enumerationTable
57 // createContext function.
58 EnumerationContext::EnumerationContext(const String& contextId,
59 const CIMNamespaceName& nameSpace,
60 Uint32 interOperationTimeoutValue,
61 Boolean continueOnError,
62 MessageType pullRequestType,
63 CIMResponseData::ResponseDataContent contentType )
64 karl 1.2 :
65 _cimException(CIMException()),
66 _savedRequest(NULL), // Clear because used as a flag
67 _contextId(contextId),
68 _nameSpace(nameSpace),
69 _operationTimeoutSec(interOperationTimeoutValue),
70 _continueOnError(continueOnError),
|
71 karl 1.3 _operationTimerUsec(0),
|
72 karl 1.2 _pullRequestType(pullRequestType),
73 _clientClosed(false),
74 _providersComplete(false),
75 _processing(true), // set true because always created during processing
76 _error(false),
77 _responseCache(contentType),
78 _providerWaitConditionMutex(Mutex::NON_RECURSIVE),
79 _totalWaitTimeUsec(0),
80 _maxWaitTimeUsec(0),
81 _pullOperationCounter(0),
82 _consecutiveZeroLenMaxObjectRequestCounter(0),
|
83 karl 1.3 _consecutiveZeroLenObjectResponseCounter(0),
|
84 karl 1.2 _responseCacheMaximumSize(0),
85 _requestCount(1),
86 _responseObjectsCount(0),
87 _requestedResponseObjectsCount(0),
|
88 karl 1.3 _totalZeroLenObjectResponseCounter(0),
89 _cacheHighWaterMark(0),
90 _poA(0)
|
91 karl 1.2 {
|
92 karl 1.3 PEGASUS_DEBUG_ASSERT(_responseCache.valid());
|
93 karl 1.2
94 // set start time for this enumeration sequence
95 _startTimeUsec = System::getCurrentTimeUsec();
96
97 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
98 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
99 "Create EnumerationContext ContextId=%s operationTimeoutSec %u"
100 " responseCacheDataType %u StartTime %lu",
101 (const char *)getContextId().getCString(),
102 _operationTimeoutSec,
103 _responseCache.getResponseDataContent(),
104 (unsigned long int)_startTimeUsec));
105 #endif
106 }
107
108 void EnumerationContext::setRequestProperties(
109 const Boolean includeClassOrigin,
110 const CIMPropertyList& propertyList)
111 {
112 // Set request properties into the responseCache that are required
113 // later for pull operations. Not required for names operations
114 karl 1.2 // since the attributes defined characteristics of objects returned
115 // (qualifiers, classorigin, propertylists).
116 // Sets includeQualifiers == false since this attribute
117 // not supported for pull operations.
118 _responseCache.setRequestProperties(
119 false, includeClassOrigin, propertyList);
120 }
121
122 /*
123 Set the inter-operation timer for the timeout to the start of the
124 next operation of this enumeration sequence. If the operationTimeout
125 value = 0 do not set the timer.
126 */
127 void EnumerationContext::startTimer()
128 {
129 PEG_METHOD_ENTER(TRC_DISPATCHER,"EnumerationContext::startTimer");
130 PEGASUS_DEBUG_ASSERT(valid());
131
132 // Request operation timeout = 0 means do not start timer
133 if (_operationTimeoutSec != 0)
134 {
|
135 karl 1.3 startTimer(_operationTimeoutSec * 1000000);
136 }
137 PEG_METHOD_EXIT();
138 }
|
139 karl 1.2
|
140 karl 1.3 void EnumerationContext::startTimer(Uint64 timeoutUsec)
141 {
142 PEG_METHOD_ENTER(TRC_DISPATCHER,"EnumerationContext::startTimer");
|
143 karl 1.2
|
144 karl 1.3 PEGASUS_DEBUG_ASSERT(valid());
145
146 Uint64 currentTime = System::getCurrentTimeUsec();
147
148 _operationTimerUsec = currentTime + timeoutUsec;
149
150 _enumerationContextTable->dispatchTimerThread((_operationTimeoutSec));
|
151 karl 1.2
152 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
|
153 karl 1.3 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
154 "StartTimer, ContextId=%s, This timeoutTime(sec)=%llu"
155 " OperationTimeout=%u sec,"
156 " next timeout in %ld sec,",
157 (const char*)getContextId().getCString(),
158 (timeoutUsec / 1000000),
159 _operationTimeoutSec,
160 (long signed int)(_operationTimerUsec - currentTime)/1000000 ));
|
161 karl 1.2 #endif
162 PEG_METHOD_EXIT();
163 }
164
165 void EnumerationContext::stopTimer()
166 {
167 PEG_METHOD_ENTER(TRC_DISPATCHER,"EnumerationContext::stopTimer");
|
168 karl 1.3
|
169 karl 1.2 PEGASUS_DEBUG_ASSERT(valid());
170
171 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
172 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
173 "StopTimer, ContextId=%s,"
|
174 karl 1.3 " OperationTimeout=%u sec,"
175 " opttime - curtime=%ld sec,",
|
176 karl 1.2 (const char*)getContextId().getCString(),
177 _operationTimeoutSec,
|
178 karl 1.3 (long signed int)(_operationTimerUsec -
|
179 karl 1.2 System::getCurrentTimeUsec())/1000000 ));
180 #endif
|
181 karl 1.3 _operationTimerUsec = 0;
|
182 karl 1.2 PEG_METHOD_EXIT();
183 }
184
185 /*
186 Test interoperation timer against current time. Return true if timed out
187 or timer set 0 zero indicating that the timer is not active.
188 Returns bool true if timer not zero and Interoperation timer
189 is greater than interoperation timeout (i.e timed out).
190 */
191 bool EnumerationContext::isTimedOut(Uint64 currentTime)
192 {
193 PEGASUS_DEBUG_ASSERT(valid());
194
|
195 karl 1.3 if (_operationTimerUsec == 0)
|
196 karl 1.2 {
197 return false;
198 }
199
|
200 karl 1.3 bool timedOut = (_operationTimerUsec < currentTime)? true : false;
|
201 karl 1.2
202 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
203 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
|
204 karl 1.3 "isTimedOut Timer. ContextId=%s timer(sec)=%lu"
205 " current(sec)=%lu time to timeout(sec)=%ld isTimedOut=%s",
|
206 karl 1.2 (const char*)_contextId.getCString(),
|
207 karl 1.3 (long unsigned int)(_operationTimerUsec / 1000000),
208 (long unsigned int)(currentTime / 1000000),
209 (long signed int)((_operationTimerUsec - currentTime) / 1000000),
|
210 karl 1.2 boolToString(timedOut) ));
211 #endif
|
212 karl 1.3 // If it is timed out, set timer inactive.
|
213 karl 1.2 if (timedOut)
214 {
|
215 karl 1.3 _operationTimerUsec = 0;
|
216 karl 1.2 }
217 return(timedOut);
218 }
219
220 bool EnumerationContext::isTimedOut()
221 {
222 Uint64 currentTime = System::getCurrentTimeUsec();
223 return isTimedOut(currentTime);
224 }
225
226 // FUTURE: In future consider list of exceptions since there may be
227 // multiples. For the moment, last error wins.
228 void EnumerationContext::setErrorState(CIMException x)
229 {
230 PEGASUS_DEBUG_ASSERT(valid());
231 // Until we handle multiple errors, return only the first error
232 if (_error)
233 {
234 return;
235 }
236 // Set exception first and use flag as indicator to avoid ipc issues.
237 karl 1.2 _cimException = x;
238 _error = true;
239 }
240
|
241 karl 1.3 //// KS_FUTURE make DEBUG compile only
|
242 karl 1.2 // Diagnostic display of data in the enumeration context object
243 void EnumerationContext::trace()
244 {
245 PEGASUS_DEBUG_ASSERT(valid());
246 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
247 "EnumerationContextTrace ContextId=%s "
248 "requestOperationTimeOut= %u "
249 "operationTimer=%lu sec "
250 "continueOnError=%s "
251 "pullMsgType=%s "
|
252 karl 1.3 "processingState=%s"
|
253 karl 1.2 "providersComplete=%s "
254 "closed=%s "
255 "timeOpen=%lu millisec "
256 "totalPullCount=%u "
257 "cacheHighWaterMark=%u "
258 "Request count=%u "
259 "ResponseObjectCount=%u "
260 "totalWaitTimeUsec=%llu"
261 "maxWaitTimeUsec=%llu"
|
262 karl 1.3 "RequestedResponseObjectCount=%u"
263 "totalZeroLenObjectResponseCounter=%u",
|
264 karl 1.2 (const char *)_contextId.getCString(),
265 _operationTimeoutSec,
|
266 karl 1.3 (long unsigned int)_operationTimerUsec,
|
267 karl 1.2 boolToString(_continueOnError),
268 MessageTypeToString(_pullRequestType),
|
269 karl 1.3 processingState(),
|
270 karl 1.2 boolToString(_providersComplete),
271 boolToString(_clientClosed),
272 (long unsigned int)
273 (System::getCurrentTimeUsec() - _startTimeUsec)/1000,
274 _pullOperationCounter,
275 _cacheHighWaterMark,
276 _requestCount,
277 _responseObjectsCount,
278 _totalWaitTimeUsec,
279 _maxWaitTimeUsec,
|
280 karl 1.3 _requestedResponseObjectsCount,
281 _totalZeroLenObjectResponseCounter ));
|
282 karl 1.2 }
283
284 /**
285 * validate the magic object for this context
286 *
287 * @return bool True if valid object.
288 */
289 bool EnumerationContext::valid() const
290 {
291 _responseCache.valid();
292 return _magic;
293 }
294
295 EnumerationContext::~EnumerationContext()
296 {
297 PEG_METHOD_ENTER(TRC_DISPATCHER,
298 "EnumerationContext::~EnumerationContext()");
299 PEG_METHOD_EXIT();
300 }
301
302 /*
303 karl 1.2 Insert complete CIMResponseData entities into the cache. If the
304 cache is at its max size limit, and there are more provider responses
305 wait until it the size drops below the full limit.
306 If the operation is closed, ignore the response.
307 Return true if putCache worked, false if closed and nothing put into
308 the cache.
309 NOTE: This function assumes that responses for a request are serialized
310 in _enqueueResponse See _enqueueResponseMutex.
311 */
312 bool EnumerationContext::putCache(CIMResponseMessage*& response,
313 bool providersComplete)
314 {
315 PEG_METHOD_ENTER(TRC_DISPATCHER, "EnumerationContext::putCache");
316
317 PEGASUS_DEBUG_ASSERT(valid());
318
319 // Design error if we ever get here with providers already set complete
320 PEGASUS_DEBUG_ASSERT(!_providersComplete);
321
322 CIMResponseDataMessage* localResponse =
323 dynamic_cast<CIMResponseDataMessage*>(response);
324 karl 1.2 CIMResponseData & from = localResponse->getResponseData();
325
326 // If there is any binary data, reformat it to SCMO. There are no
327 // size counters for the binary data so we reformat to generate
328 // counters.
329 if (from.hasBinaryData())
330 {
331 from.resolveBinaryToSCMO();
332 }
333
334 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
335 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
|
336 karl 1.3 "putCache, ContextId=%s isComplete=%s ResponseDataType=%u "
337 " cache size=%u put size=%u clientClosed=%s",
|
338 karl 1.2 (const char*)getContextId().getCString(),
339 boolToString(providersComplete),
340 _responseCache.getResponseDataContent(),
341 _responseCache.size(), from.size(),
342 boolToString(_clientClosed)));
343 #endif
344
345 // If an operation has closed the enumerationContext
346 // ignore any received responses until the providersComplete is received
347 // and then remove the Context.
348 if (_clientClosed)
349 {
350 PEG_METHOD_EXIT();
351 return false;
352 }
353 else // client not closed
354 {
355 // put the current response into the cache. Lock cache for this
356 // operation
357
358 _responseCache.appendResponseData(from);
359 karl 1.2
360 // set providersComplete flag from flag in call parameter.
361 _providersComplete = providersComplete;
362
363 // test and set the high water mark for this cache.
364 if (responseCacheSize() > _cacheHighWaterMark)
365 {
366 _cacheHighWaterMark = responseCacheSize();
367 }
368 }
369
370 // Return true indicating that input added to cache and cache is still open
|
371 karl 1.3 PEG_METHOD_EXIT();
|
372 karl 1.2 return true;
373 }
374
375 // Wait until cache size drops below defined limit. Saves time
376 // in wait in EnumerationContext for statistics and uses
377 // waitProviderLimitCondition condition variable.
378 void EnumerationContext::waitCacheSize()
379 {
380 PEG_METHOD_ENTER(TRC_DISPATCHER, "EnumerationContext::waitCacheSize()");
381
382 PEGASUS_DEBUG_ASSERT(valid());
383
384 _providerWaitConditionMutex.lock();
385
386 Uint64 startTime = System::getCurrentTimeUsec();
387
388 while ((!_clientClosed) && (responseCacheSize() > _responseCacheMaximumSize)
389 && !_providersComplete)
390 {
391 _providerWaitCondition.wait(_providerWaitConditionMutex);
392 }
393 karl 1.2
394 _providerWaitConditionMutex.unlock();
395
396 Uint64 interval = System::getCurrentTimeUsec() - startTime;
397
398 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
399 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
400 "waitCacheSize ContextId=%s Wait %lu usec",
401 (const char *)_contextId.getCString(),
402 (unsigned long int)interval ));
403 #endif
404
405 _totalWaitTimeUsec += interval;
406 if (interval > _maxWaitTimeUsec)
407 {
408 _maxWaitTimeUsec = interval;
409 }
410 PEG_METHOD_EXIT();
411 }
412
413
414 karl 1.2 /*****************************************************************************
415 **
416 ** Methods to support the EnumerationContext CIMResponseData Cache
417 **
418 *****************************************************************************/
419
420 /*
421 Test the cache to see if there is information that could be used
422 for an immediate response. Returns immediatly with true or false
423 indicating that a response should be issued.
424 @param count Uint32 count of objects that the requests set as
425 max number for response
426 @return True if passes tests for something to send or error flag
427 set.
428 */
429 bool EnumerationContext::testCacheForResponses(
430 Uint32 operationMaxObjectCount,
431 bool requiresAll)
432 {
433 bool rtn = false;
434
435 karl 1.2 // Error encountered, must send response. This makes error highest
436 // priority.
437 if (isErrorState())
438 {
439 rtn = true;
440 }
441 // Always allow requests for no objects
442 else if (operationMaxObjectCount == 0)
443 {
444 rtn = true;
445 }
446 // If cache has enough objects return true
447 else if (requiresAll && (responseCacheSize() >= operationMaxObjectCount))
448 {
449 rtn = true;
450 }
451 // anything in cache to return
452 else if (!requiresAll && responseCacheSize() > 0)
453 {
454 rtn = true;
455 }
456 karl 1.2 // Nothing more from providers. Must return response
457 else if (providersComplete())
458 {
459 rtn = true;
460 }
461
462 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
463 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
464 "testCacheForResponse returns %s", boolToString(rtn) ));
465 #endif
466 return rtn;
467 }
468
469 void EnumerationContext::saveNextResponse(
470 CIMOperationRequestMessage* request,
471 CIMOpenOrPullResponseDataMessage* response,
472 Uint32 operationMaxObjectCount)
473 {
474 // Since _savedRequest is also flag, it MUST BE empty when this function
475 // called.
476 PEGASUS_DEBUG_ASSERT(_savedRequest == NULL);
477 karl 1.2
478 _savedOperationMaxObjectCount = operationMaxObjectCount;
479 _savedResponse = response;
480 _savedRequest = request;
481 }
482 /*
483 Move the number of objects defined by count from the CIMResponseData
484 cache for this EnumerationContext to theCIMResponseData object
485 defined by the input parameter.
486
487 Returns true if data acquired from cache. Returns false if CIMException
488 found (i.e. returned an error).
489 */
490 bool EnumerationContext::getCache(Uint32 count, CIMResponseData& rtnData)
491 {
492 PEG_METHOD_ENTER(TRC_DISPATCHER, "EnumerationContext::getCache");
493
494 PEGASUS_DEBUG_ASSERT(valid());
495
496 // Move attributes from Cache to new CIMResponseData object
497 // sets the attributes for propertyList, includeQualifiers,
498 karl 1.2 // classOrigin
499 rtnData.setResponseAttributes(_responseCache);
500
501 // if Error set, return false to signal the error to caller.
502 if (isErrorState())
503 {
504 PEG_METHOD_EXIT();
505 return false;
506 }
507
508 // Move the defined number of objects from the cache to the return object.
509 rtnData.moveObjects(_responseCache, count);
510
511 // add to statistics for this enumerationContext
512 _responseObjectsCount += rtnData.size();
513 _requestedResponseObjectsCount += count;
514
515 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
516 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
517 "EnumerationContext::getCache ContextId=%s moveObjects expected=%u"
518 " actual %u", (const char *)getContextId().getCString(),
519 karl 1.2 count, rtnData.size()));
520 #endif
521
522 // Signal the ProviderLimitCondition that the cache size may
523 // have changed.
524 signalProviderWaitCondition();
525
526 PEG_METHOD_EXIT();
527 return true;
528 }
529
530 void EnumerationContext::signalProviderWaitCondition()
531 {
532 PEG_METHOD_ENTER(TRC_DISPATCHER,
533 "EnumerationContext::signalProviderLimitCondition");
534
535 PEGASUS_DEBUG_ASSERT(valid());
536
537 AutoMutex autoMut(_providerWaitConditionMutex);
538
539 _providerWaitCondition.signal();
540 karl 1.2
541 PEG_METHOD_EXIT();
542 }
543
544 // Update counters for Pull and test for too many consecutive zero
545 // length requests.
546 // return true if too many. Else return false.
547 bool EnumerationContext::incAndTestPullCounters(bool isZeroLength)
548 {
549 PEGASUS_DEBUG_ASSERT(valid());
550
551 _pullOperationCounter++;
552
553 if (isZeroLength)
554 {
555 _consecutiveZeroLenMaxObjectRequestCounter++;
556 }
557 else
558 {
559 _consecutiveZeroLenMaxObjectRequestCounter = 0;
560 }
561 karl 1.2 return (_consecutiveZeroLenMaxObjectRequestCounter >
562 MAX_ZERO_PULL_OPERATIONS);
563 }
564
565 // set providers complete flag and signal the CacheSizeCondition.
566 // This could awaken any wait at the cacheWait.
567 void EnumerationContext::setProvidersComplete()
568 {
569 PEG_METHOD_ENTER(TRC_DISPATCHER,
570 "EnumerationContext::setProvidersComplete");
571
572 PEGASUS_DEBUG_ASSERT(valid());
573
574 _providersComplete = true;
575
576 PEG_METHOD_EXIT();
577 }
578
579 // End of Request operation processing. Set the next enumeration state.
580 // If providers Complete and cache = 0. We can now close the enumeration.
581 // If no more from providers and no more in cache, we set the client closed
582 karl 1.2 //
583 // Returns true if there is no more to process (providers are complete and
584 // responseCacheSize = 0). Returns false if providers not complete or
585 // there is data in the cache
586
587 bool EnumerationContext::setNextEnumerationState(bool errorFound)
588 {
589 PEG_METHOD_ENTER(TRC_DISPATCHER,
590 "EnumerationContext::setNextEnumerationState");
591
592 PEGASUS_DEBUG_ASSERT(valid());
593
594 // Return true if client closed because of error or all responses complete,
595 // else set ProcessingState false and return false
596 if ((providersComplete() && (responseCacheSize() == 0)) ||
597 (errorFound && !_continueOnError))
598 {
599 setClientClosed();
600 return true;
601 }
602
603 karl 1.2 // Otherwise, set processing state to inactive and start operation
604 // timer
605 setProcessingState(false);
606
607 PEG_METHOD_EXIT();
608 return false;
609 }
610
611 void EnumerationContext::setClientClosed()
612 {
613 PEGASUS_DEBUG_ASSERT(valid());
614
615 _clientClosed = true;
616
617 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
618 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
619 "setClientClosed. ContextId=%s ",
620 (const char*)getContextId().getCString() ));
621 #endif
622
623 // Clear any existing responses out of the cache. The will never
624 karl 1.2 // be used.
625 _responseCache.clear();
626
627 if (!_providersComplete)
628 {
629 // Signal that cache size has dropped.
630 signalProviderWaitCondition();
631 }
632 }
633
|
634 karl 1.3 const char* EnumerationContext::processingState()
635 {
636 static const char * active = "active";
637 static const char * inactive = "inactive";
638 return (_processing? active: inactive);
639 }
640
|
641 karl 1.2 /*
642 Set the processing state. Processing is true if the Dispatcher is
643 actively handling a request. The dispatcher sets processing = true
644 at the start of processing and false at the completion of processing.
645 */
646 void EnumerationContext::setProcessingState(bool state)
647 {
648 // Diagnostic to confirm we are changing state
649 PEGASUS_DEBUG_ASSERT(valid());
|
650 karl 1.3 PEGASUS_DEBUG_ASSERT(_processing != state); // not setting to same state
|
651 karl 1.2
652 #ifdef ENUMERATION_CONTEXT_DIAGNOSTIC_TRACE
653 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
654 "setProcessingState. ContextId=%s nextProcessingStat=%s",
655 (const char*)getContextId().getCString(),
656 (state? "active" : "inactive") ));
657 #endif
658
659 _processing = state;
660 if (_processing)
661 {
662 stopTimer();
663 }
664 else
665 {
666 startTimer();
667 }
668 }
669
670 PEGASUS_NAMESPACE_END
|