(file) Return to Thread.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/Thread.cpp between version 1.89.12.2 and 1.90.2.7

version 1.89.12.2, 2006/06/29 22:50:04 version 1.90.2.7, 2006/07/29 01:08:49
Line 43 
Line 43 
  
 #include "Thread.h" #include "Thread.h"
 #include <exception> #include <exception>
 #include <Pegasus/Common/IPC.h>  
 #include <Pegasus/Common/Tracer.h> #include <Pegasus/Common/Tracer.h>
   #include "Time.h"
  
 #if defined(PEGASUS_OS_TYPE_WINDOWS)  PEGASUS_USING_STD;
 # include "ThreadWindows.cpp"  
 #elif defined(PEGASUS_OS_TYPE_UNIX)  PEGASUS_NAMESPACE_BEGIN
 # include "ThreadUnix.cpp"  
 #elif defined(PEGASUS_OS_TYPE_NSK)  //==============================================================================
 # include "ThreadNsk.cpp"  //
 #elif defined(PEGASUS_OS_VMS)  // POSIX Threads Implementation:
 # include "ThreadVms.cpp"  //
   //==============================================================================
   
   #if defined(PEGASUS_HAVE_PTHREADS)
   
   extern "C" void *_start_wrapper(void *arg_)
   {
       StartWrapperArg *arg = (StartWrapperArg *) arg_;
   
       void *return_value = (*arg->start) (arg->arg);
       delete arg;
   
       return return_value;
   }
   
   static sigset_t *block_signal_mask(sigset_t * sig)
   {
       sigemptyset(sig);
       // should not be used for main()
       sigaddset(sig, SIGHUP);
       sigaddset(sig, SIGINT);
       // maybe useless, since KILL can't be blocked according to POSIX
       sigaddset(sig, SIGKILL);
   
       sigaddset(sig, SIGABRT);
       sigaddset(sig, SIGALRM);
       sigaddset(sig, SIGPIPE);
   
   
   // Note: older versions of the linux pthreads library use SIGUSR1 and SIGUSR2
   // internally to stop and start threads that are blocking, the newer ones
   // implement this through the kernel's real time signals
   // since SIGSTOP/CONT can handle suspend()/resume() on Linux
   // block them
   // #if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU)
   //     sigaddset(sig, SIGUSR1);
   //     sigaddset(sig, SIGUSR2);
   // #endif
   #ifndef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM
       pthread_sigmask(SIG_BLOCK, sig, NULL);
 #else #else
 # error "Unsupported platform"      sigprocmask(SIG_BLOCK, sig, NULL);
 #endif #endif
       return sig;
   }
  
 PEGASUS_USING_STD;  Thread::Thread(ThreadReturnType(PEGASUS_THREAD_CDECL * start) (void *), void *parameter, Boolean detached):_is_detached(detached),
 PEGASUS_NAMESPACE_BEGIN  _cancel_enabled(true),
   _cancelled(false),
   _start(start), _cleanup(), _tsd(), _thread_parm(parameter), _exit_code(0)
   {
       Threads::clear(_handle.thid);
   }
   
   Thread::~Thread()
   {
       try
       {
           join();
           empty_tsd();
       }
       catch(...)
       {
           // Do not allow the destructor to throw an exception
       }
   }
  
   #endif /* PEGASUS_HAVE_PTHREADS */
   
   //==============================================================================
   //
   // Windows Threads Implementation:
   //
   //==============================================================================
   
   #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
   
   Thread::Thread(ThreadReturnType(PEGASUS_THREAD_CDECL * start) (void *),
                  void *parameter,
                  Boolean detached):_is_detached(detached),
   _cancel_enabled(true),
   _cancelled(false),
   _start(start), _cleanup(), _tsd(), _thread_parm(parameter), _exit_code(0)
   {
       Threads::clear(_handle.thid);
   }
   
   Thread::~Thread()
   {
       try
       {
           join();
           empty_tsd();
       }
       catch(...)
       {
       }
   }
   
   #endif /* PEGASUS_HAVE_WINDOWS_THREADS */
   
   //==============================================================================
   //
   // Common implementation:
   //
   //==============================================================================
  
 void thread_data::default_delete(void * data) void thread_data::default_delete(void * data)
 { {
Line 68 
Line 166 
       ::operator delete(data);       ::operator delete(data);
 } }
  
 // l10n start  
 void language_delete(void * data) void language_delete(void * data)
 { {
    if( data != NULL)    if( data != NULL)
    {    {
       AutoPtr<AcceptLanguageList> al(static_cast<AcceptLanguageList *>(data));          AutoPtr < AcceptLanguageList > al(static_cast <
                                             AcceptLanguageList * >(data));
    }    }
 } }
 // l10n end  
  
 Boolean Thread::_signals_blocked = false; Boolean Thread::_signals_blocked = false;
 // l10n  
 #ifndef PEGASUS_OS_ZOS #ifndef PEGASUS_OS_ZOS
 PEGASUS_THREAD_KEY_TYPE Thread::_platform_thread_key = PEGASUS_THREAD_KEY_TYPE(-1);  TSDKeyType Thread::_platform_thread_key = TSDKeyType(-1);
 #else #else
 PEGASUS_THREAD_KEY_TYPE Thread::_platform_thread_key;  TSDKeyType Thread::_platform_thread_key;
 #endif #endif
 Boolean Thread::_key_initialized = false; Boolean Thread::_key_initialized = false;
 Boolean Thread::_key_error = false; Boolean Thread::_key_error = false;
  
   
 void Thread::cleanup_push( void (*routine)(void *), void *parm) void Thread::cleanup_push( void (*routine)(void *), void *parm)
 { {
     AutoPtr<cleanup_handler> cu(new cleanup_handler(routine, parm));     AutoPtr<cleanup_handler> cu(new cleanup_handler(routine, parm));
Line 116 
Line 211 
 //thread_data *Thread::put_tsd(const Sint8 *key, void (*delete_func)(void *), Uint32 size, void *value) //thread_data *Thread::put_tsd(const Sint8 *key, void (*delete_func)(void *), Uint32 size, void *value)
  
  
 #ifndef PEGASUS_THREAD_EXIT_NATIVE  void Thread::exit_self(ThreadReturnType exit_code)
 void Thread::exit_self(PEGASUS_THREAD_RETURN exit_code)  
 { {
   #if defined(PEGASUS_PLATFORM_HPUX_ACC) || \
       defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
       // NOTE: pthread_exit exhibits unusual behavior on RHEL 3 U2, as
       // documented in Bugzilla 3836.  Where feasible, it may be advantageous
       // to avoid using this function.
       pthread_exit(exit_code);
   #else
     // execute the cleanup stack and then return     // execute the cleanup stack and then return
    while( _cleanup.size() )    while( _cleanup.size() )
    {    {
Line 133 
Line 234 
        }        }
    }    }
    _exit_code = exit_code;    _exit_code = exit_code;
    exit_thread(exit_code);      Threads::exit(exit_code);
    _handle.thid = 0;      Threads::clear(_handle.thid);
 }  
   
   
 #endif #endif
   }
  
 // l10n start  
 Sint8 Thread::initializeKey() Sint8 Thread::initializeKey()
 { {
     PEG_METHOD_ENTER(TRC_THREAD, "Thread::initializeKey");     PEG_METHOD_ENTER(TRC_THREAD, "Thread::initializeKey");
Line 153 
Line 251 
             return -1;             return -1;
         }         }
  
         if (pegasus_key_create(&Thread::_platform_thread_key) == 0)          if (TSDKey::create(&Thread::_platform_thread_key) == 0)
         {         {
             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,
                 "Thread: able to create a thread key");                 "Thread: able to create a thread key");
Line 180 
Line 278 
         return NULL;         return NULL;
     }     }
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     return (Thread *)pegasus_get_thread_specific(_platform_thread_key);      return (Thread *) TSDKey::get_thread_specific(_platform_thread_key);
 } }
  
 void Thread::setCurrent(Thread * thrd) void Thread::setCurrent(Thread * thrd)
Line 188 
Line 286 
     PEG_METHOD_ENTER(TRC_THREAD, "Thread::setCurrent");     PEG_METHOD_ENTER(TRC_THREAD, "Thread::setCurrent");
     if (Thread::initializeKey() == 0)     if (Thread::initializeKey() == 0)
     {     {
         if (pegasus_set_thread_specific(          if (TSDKey::
                Thread::_platform_thread_key, (void *) thrd) == 0)              set_thread_specific(Thread::_platform_thread_key,
                                   (void *) thrd) == 0)
         {         {
             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,
                 "Successful set Thread * into thread specific storage");                 "Successful set Thread * into thread specific storage");
Line 227 
Line 326 
         // deletes the old tsd and creates a new one         // deletes the old tsd and creates a new one
         currentThrd->put_tsd("acceptLanguages",         currentThrd->put_tsd("acceptLanguages",
             language_delete,             language_delete,
             sizeof(AcceptLanguageList *),                               sizeof (AcceptLanguageList *), langs);
             langs);  
     }     }
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
Line 247 
Line 345 
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
 // l10n end  
   
  
 /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
 // //
Line 256 
Line 352 
 // //
 /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
  
 ThreadPool::ThreadPool(  ThreadPool::ThreadPool(Sint16 initialSize,
     Sint16 initialSize,  
     const char* key,     const char* key,
     Sint16 minThreads,     Sint16 minThreads,
     Sint16 maxThreads,     Sint16 maxThreads,
     struct timeval& deallocateWait)                         struct timeval
     : _maxThreads(maxThreads),                         &deallocateWait):_maxThreads(maxThreads),
       _minThreads(minThreads),  _minThreads(minThreads), _currentThreads(0), _idleThreads(),
       _currentThreads(0),  _runningThreads(), _dying(0)
       _idleThreads(),  
       _runningThreads(),  
       _dying(0)  
 { {
     _deallocateWait.tv_sec = deallocateWait.tv_sec;     _deallocateWait.tv_sec = deallocateWait.tv_sec;
     _deallocateWait.tv_usec = deallocateWait.tv_usec;     _deallocateWait.tv_usec = deallocateWait.tv_usec;
Line 300 
Line 392 
  
     try     try
     {     {
         // Set the dying flag so all thread know the destructor has been entered          // Set the dying flag so all thread know the destructor has been
           // entered
         _dying++;         _dying++;
        Tracer::trace(TRC_THREAD, Tracer::LEVEL2,        Tracer::trace(TRC_THREAD, Tracer::LEVEL2,
                 "Cleaning up %d idle threads. ", _currentThreads.get());                 "Cleaning up %d idle threads. ", _currentThreads.get());
   
         while (_currentThreads.get() > 0)         while (_currentThreads.get() > 0)
         {         {
             Thread* thread = _idleThreads.remove_front();             Thread* thread = _idleThreads.remove_front();
Line 314 
Line 408 
             }             }
             else             else
             {             {
                 pegasus_yield();                  Threads::yield();
             }             }
         }         }
     }     }
Line 323 
Line 417 
     }     }
 } }
  
 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL ThreadPool::_loop(void* parm)  ThreadReturnType PEGASUS_THREAD_CDECL ThreadPool::_loop(void *parm)
 { {
     PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::_loop");     PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::_loop");
  
Line 349 
Line 443 
             PEGASUS_ASSERT(sleep_sem != 0);             PEGASUS_ASSERT(sleep_sem != 0);
  
             lastActivityTime =             lastActivityTime =
                 (struct timeval *)myself->reference_tsd("last activity time");                  (struct timeval *) myself->
                   reference_tsd("last activity time");
             myself->dereference_tsd();             myself->dereference_tsd();
             PEGASUS_ASSERT(lastActivityTime != 0);             PEGASUS_ASSERT(lastActivityTime != 0);
         }         }
Line 362 
Line 457 
             pool->_idleThreads.remove(myself);             pool->_idleThreads.remove(myself);
             pool->_currentThreads--;             pool->_currentThreads--;
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             return((PEGASUS_THREAD_RETURN)1);              return ((ThreadReturnType) 1);
         }         }
  
         while (1)         while (1)
Line 379 
Line 474 
                 pool->_idleThreads.remove(myself);                 pool->_idleThreads.remove(myself);
                 pool->_currentThreads--;                 pool->_currentThreads--;
                 PEG_METHOD_EXIT();                 PEG_METHOD_EXIT();
                 return((PEGASUS_THREAD_RETURN)1);                  return ((ThreadReturnType) 1);
             }             }
  
             // When we awaken we reside on the _runningThreads queue, not the             // When we awaken we reside on the _runningThreads queue, not the
             // _idleThreads queue.             // _idleThreads queue.
  
             PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL* work)(void *) = 0;              ThreadReturnType(PEGASUS_THREAD_CDECL * work) (void *) = 0;
             void* parm = 0;             void* parm = 0;
             Semaphore* blocking_sem = 0;             Semaphore* blocking_sem = 0;
  
             try             try
             {             {
                 work = (PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *))                  work = (ThreadReturnType(PEGASUS_THREAD_CDECL *) (void *))
                     myself->reference_tsd("work func");                     myself->reference_tsd("work func");
                 myself->dereference_tsd();                 myself->dereference_tsd();
                 parm = myself->reference_tsd("work parm");                 parm = myself->reference_tsd("work parm");
                 myself->dereference_tsd();                 myself->dereference_tsd();
                 blocking_sem = (Semaphore *)myself->reference_tsd("blocking sem");                  blocking_sem =
                       (Semaphore *) myself->reference_tsd("blocking sem");
                 myself->dereference_tsd();                 myself->dereference_tsd();
             }             }
             catch (...)             catch (...)
Line 408 
Line 504 
                 pool->_idleThreads.remove(myself);                 pool->_idleThreads.remove(myself);
                 pool->_currentThreads--;                 pool->_currentThreads--;
                 PEG_METHOD_EXIT();                 PEG_METHOD_EXIT();
                 return((PEGASUS_THREAD_RETURN)1);                  return ((ThreadReturnType) 1);
             }             }
  
             if (work == 0)             if (work == 0)
Line 418 
Line 514 
                 break;                 break;
             }             }
  
             gettimeofday(lastActivityTime, NULL);              Time::gettimeofday(lastActivityTime);
  
             try             try
             {             {
                 PEG_TRACE_STRING(TRC_THREAD, Tracer::LEVEL4, "Work starting.");                  PEG_TRACE_STRING(TRC_THREAD, Tracer::LEVEL4,
                                    "Work starting.");
                 work(parm);                 work(parm);
                 PEG_TRACE_STRING(TRC_THREAD, Tracer::LEVEL4, "Work finished.");                  PEG_TRACE_STRING(TRC_THREAD, Tracer::LEVEL4,
                                    "Work finished.");
             }             }
             catch (Exception & e)             catch (Exception & e)
             {             {
                 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,                 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                     String("Exception from work in ThreadPool::_loop: ") +                                   String
                         e.getMessage());                                   ("Exception from work in ThreadPool::_loop: ")
                                    + e.getMessage());
             }             }
 #if !defined(PEGASUS_OS_LSB) #if !defined(PEGASUS_OS_LSB)
             catch (const exception& e)             catch (const exception& e)
             {             {
                 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,                 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                     String("Exception from work in ThreadPool::_loop: ") +                                   String
                         e.what());                                   ("Exception from work in ThreadPool::_loop: ")
                                    + e.what());
             }             }
 #endif #endif
             catch (...)             catch (...)
Line 449 
Line 549 
             // put myself back onto the available list             // put myself back onto the available list
             try             try
             {             {
                 gettimeofday(lastActivityTime, NULL);                  Time::gettimeofday(lastActivityTime);
                 if (blocking_sem != 0)                 if (blocking_sem != 0)
                 {                 {
                     blocking_sem->signal();                     blocking_sem->signal();
Line 465 
Line 565 
                 PEGASUS_ASSERT(false);                 PEGASUS_ASSERT(false);
                 pool->_currentThreads--;                 pool->_currentThreads--;
                 PEG_METHOD_EXIT();                 PEG_METHOD_EXIT();
                 return((PEGASUS_THREAD_RETURN)1);                  return ((ThreadReturnType) 1);
             }             }
         }         }
     }     }
     catch (const Exception& e)     catch (const Exception& e)
     {     {
         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,         PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
             "Caught exception: \"" + e.getMessage() + "\".  Exiting _loop.");                           "Caught exception: \"" + e.getMessage() +
                            "\".  Exiting _loop.");
     }     }
     catch (...)     catch (...)
     {     {
Line 481 
Line 582 
     }     }
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     return((PEGASUS_THREAD_RETURN)0);      return ((ThreadReturnType) 0);
 } }
  
 ThreadStatus ThreadPool::allocate_and_awaken(  ThreadStatus ThreadPool::allocate_and_awaken(void *parm,
     void* parm,                                               ThreadReturnType
     PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL* work)(void *),                                               (PEGASUS_THREAD_CDECL *
                                                 work) (void *),
     Semaphore* blocking)     Semaphore* blocking)
 { {
     PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::allocate_and_awaken");     PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::allocate_and_awaken");
Line 504 
Line 606 
             return PEGASUS_THREAD_UNAVAILABLE;             return PEGASUS_THREAD_UNAVAILABLE;
         }         }
         struct timeval start;         struct timeval start;
         gettimeofday(&start, NULL);          Time::gettimeofday(&start);
         Thread* th = 0;         Thread* th = 0;
  
         th = _idleThreads.remove_front();         th = _idleThreads.remove_front();
Line 539 
Line 641 
  
         th->delete_tsd("work func");         th->delete_tsd("work func");
         th->put_tsd("work func", NULL,         th->put_tsd("work func", NULL,
             sizeof( PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *)),                      sizeof (ThreadReturnType(PEGASUS_THREAD_CDECL *)
             (void *)work);                              (void *)), (void *) work);
         th->delete_tsd("work parm");         th->delete_tsd("work parm");
         th->put_tsd("work parm", NULL, sizeof(void *), parm);         th->put_tsd("work parm", NULL, sizeof(void *), parm);
         th->delete_tsd("blocking sem");         th->delete_tsd("blocking sem");
Line 590 
Line 692 
  
         Thread* thread = _idleThreads.remove_back();         Thread* thread = _idleThreads.remove_back();
  
         // If there are no more threads in the _idleThreads queue, we're done.          // If there are no more threads in the _idleThreads queue, we're
           // done.
         if (thread == 0)         if (thread == 0)
         {         {
             break;             break;
Line 599 
Line 702 
         struct timeval* lastActivityTime;         struct timeval* lastActivityTime;
         try         try
         {         {
             lastActivityTime = (struct timeval *)thread->try_reference_tsd(              lastActivityTime =
                 "last activity time");                  (struct timeval *) thread->
                   try_reference_tsd("last activity time");
             PEGASUS_ASSERT(lastActivityTime != 0);             PEGASUS_ASSERT(lastActivityTime != 0);
         }         }
         catch (...)         catch (...)
Line 636 
Line 740 
  
     // Set the "work func" and "work parm" to 0 so _loop() knows to exit.     // Set the "work func" and "work parm" to 0 so _loop() knows to exit.
     thread->delete_tsd("work func");     thread->delete_tsd("work func");
     thread->put_tsd(      thread->put_tsd("work func", 0,
         "work func", 0,                      sizeof (ThreadReturnType(PEGASUS_THREAD_CDECL *)
         sizeof(PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *)),                              (void *)), (void *) 0);
         (void *) 0);  
     thread->delete_tsd("work parm");     thread->delete_tsd("work parm");
     thread->put_tsd("work parm", 0, sizeof(void *), 0);     thread->put_tsd("work parm", 0, sizeof(void *), 0);
  
Line 655 
Line 758 
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
  
 Boolean ThreadPool::_timeIntervalExpired(  Boolean ThreadPool::_timeIntervalExpired(struct timeval *start,
     struct timeval* start,  
     struct timeval* interval)     struct timeval* interval)
 { {
     // never time out if the interval is zero     // never time out if the interval is zero
Line 667 
Line 769 
  
     struct timeval now, finish, remaining;     struct timeval now, finish, remaining;
     Uint32 usec;     Uint32 usec;
     pegasus_gettimeofday(&now);      Time::gettimeofday(&now);
     pegasus_gettimeofday(&remaining);    // Avoid valgrind error      Time::gettimeofday(&remaining);     // Avoid valgrind error
  
     finish.tv_sec = start->tv_sec + interval->tv_sec;     finish.tv_sec = start->tv_sec + interval->tv_sec;
     usec = start->tv_usec + interval->tv_usec;     usec = start->tv_usec + interval->tv_usec;
Line 676 
Line 778 
     usec %= 1000000;     usec %= 1000000;
     finish.tv_usec = usec;     finish.tv_usec = usec;
  
     return (timeval_subtract(&remaining, &finish, &now) != 0);      return (Time::subtract(&remaining, &finish, &now) != 0);
 } }
  
 void ThreadPool::_deleteSemaphore(void *p) void ThreadPool::_deleteSemaphore(void *p)
Line 694 
Line 796 
     // initial count is zero, loop function will sleep until     // initial count is zero, loop function will sleep until
     // we signal the semaphore     // we signal the semaphore
     Semaphore* sleep_sem = (Semaphore *) new Semaphore(0);     Semaphore* sleep_sem = (Semaphore *) new Semaphore(0);
     th->put_tsd(      th->put_tsd("sleep sem", &_deleteSemaphore, sizeof (Semaphore),
         "sleep sem", &_deleteSemaphore, sizeof(Semaphore), (void *)sleep_sem);                  (void *) sleep_sem);
  
     struct timeval* lastActivityTime =     struct timeval* lastActivityTime =
         (struct timeval *) ::operator new(sizeof(struct timeval));         (struct timeval *) ::operator new(sizeof(struct timeval));
     pegasus_gettimeofday(lastActivityTime);      Time::gettimeofday(lastActivityTime);
  
     th->put_tsd("last activity time", thread_data::default_delete,     th->put_tsd("last activity time", thread_data::default_delete,
         sizeof(struct timeval), (void *)lastActivityTime);         sizeof(struct timeval), (void *)lastActivityTime);
Line 713 
Line 815 
         return 0;         return 0;
     }     }
     _currentThreads++;     _currentThreads++;
     pegasus_yield();      Threads::yield();
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     return th;     return th;
Line 740 
Line 842 
     }     }
 } }
  
   // ATTN: not sure where to put this!
   #ifdef PEGASUS_ZOS_SECURITY
   bool isEnhancedSecurity = 99;
   #endif
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.89.12.2  
changed lines
  Added in v.1.90.2.7

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2