(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.83 and 1.90.2.4

version 1.83, 2005/05/13 20:53:58 version 1.90.2.4, 2006/07/28 21:22:01
Line 1 
Line 1 
 //%2005////////////////////////////////////////////////////////////////////////  //%2006////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
Line 8 
Line 8 
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 // EMC Corporation; VERITAS Software Corporation; The Open Group. // 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 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
Line 41 
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) #if defined(PEGASUS_OS_TYPE_WINDOWS)
 # include "ThreadWindows.cpp" # include "ThreadWindows.cpp"
Line 71 
Line 73 
 { {
    if( data != NULL)    if( data != NULL)
    {    {
       AutoPtr<AcceptLanguages> al(static_cast<AcceptLanguages *>(data));        AutoPtr<AcceptLanguageList> al(static_cast<AcceptLanguageList *>(data));
    }    }
 } }
 // l10n end // l10n end
Line 79 
Line 81 
 Boolean Thread::_signals_blocked = false; Boolean Thread::_signals_blocked = false;
 // l10n // 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;
  
  
 // for non-native implementations  
 #ifndef PEGASUS_THREAD_CLEANUP_NATIVE  
 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));
     _cleanup.insert_first(cu.get());      _cleanup.insert_front(cu.get());
     cu.release();     cu.release();
     return;     return;
 } }
Line 102 
Line 102 
     AutoPtr<cleanup_handler> cu;     AutoPtr<cleanup_handler> cu;
     try     try
     {     {
         cu.reset(_cleanup.remove_first());          cu.reset(_cleanup.remove_front());
     }     }
     catch(IPCException&)     catch(IPCException&)
     {     {
Line 112 
Line 112 
         cu->execute();         cu->execute();
 } }
  
 #endif  
   
  
 //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 #ifndef PEGASUS_THREAD_EXIT_NATIVE
 void Thread::exit_self(PEGASUS_THREAD_RETURN exit_code)  void Thread::exit_self(ThreadReturnType exit_code)
 { {
     // execute the cleanup stack and then return     // execute the cleanup stack and then return
    while( _cleanup.count() )     while( _cleanup.size() )
    {    {
        try        try
        {        {
Line 135 
Line 133 
        }        }
    }    }
    _exit_code = exit_code;    _exit_code = exit_code;
    exit_thread(exit_code);     Threads::exit(exit_code);
    _handle.thid = 0;     Threads::clear(_handle.thid);
 } }
  
  
Line 155 
Line 153 
             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 182 
Line 180 
         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 190 
Line 188 
     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::set_thread_specific(
                Thread::_platform_thread_key, (void *) thrd) == 0)                Thread::_platform_thread_key, (void *) thrd) == 0)
         {         {
             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,
Line 205 
Line 203 
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
  
 AcceptLanguages * Thread::getLanguages()  AcceptLanguageList * Thread::getLanguages()
 { {
     PEG_METHOD_ENTER(TRC_THREAD, "Thread::getLanguages");     PEG_METHOD_ENTER(TRC_THREAD, "Thread::getLanguages");
  
     Thread * curThrd = Thread::getCurrent();     Thread * curThrd = Thread::getCurrent();
     if (curThrd == NULL)     if (curThrd == NULL)
         return NULL;         return NULL;
     AcceptLanguages * acceptLangs =      AcceptLanguageList * acceptLangs =
         (AcceptLanguages *)curThrd->reference_tsd("acceptLanguages");          (AcceptLanguageList *)curThrd->reference_tsd("acceptLanguages");
     curThrd->dereference_tsd();     curThrd->dereference_tsd();
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     return acceptLangs;     return acceptLangs;
 } }
  
 void Thread::setLanguages(AcceptLanguages *langs) //l10n  void Thread::setLanguages(AcceptLanguageList *langs) //l10n
 { {
     PEG_METHOD_ENTER(TRC_THREAD, "Thread::setLanguages");     PEG_METHOD_ENTER(TRC_THREAD, "Thread::setLanguages");
  
Line 229 
Line 227 
         // 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(AcceptLanguages *),              sizeof(AcceptLanguageList *),
             langs);             langs);
     }     }
  
Line 267 
Line 265 
     : _maxThreads(maxThreads),     : _maxThreads(maxThreads),
       _minThreads(minThreads),       _minThreads(minThreads),
       _currentThreads(0),       _currentThreads(0),
       _idleThreads(true),        _idleThreads(),
       _runningThreads(true),        _runningThreads(),
       _dying(0)       _dying(0)
 { {
     _deallocateWait.tv_sec = deallocateWait.tv_sec;     _deallocateWait.tv_sec = deallocateWait.tv_sec;
Line 299 
Line 297 
 ThreadPool::~ThreadPool() ThreadPool::~ThreadPool()
 { {
     PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::~ThreadPool");     PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::~ThreadPool");
   
     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,
                   "Cleaning up %d idle threads. ", _currentThreads.get());
  
         while (_currentThreads.value() > 0)  printf("***BEFORE\n");
           while (_currentThreads.get() > 0)
         {         {
             Thread* thread = _idleThreads.remove_first();              Thread* thread = _idleThreads.remove_front();
             if (thread != 0)             if (thread != 0)
             {             {
   printf("***INSIDE1\n");
                 _cleanupThread(thread);                 _cleanupThread(thread);
                 _currentThreads--;                 _currentThreads--;
             }             }
             else             else
             {             {
                 pegasus_yield();  printf("***INSIDE2\n");
                   Threads::yield();
             }             }
         }         }
   printf("***AFTER\n");
     }     }
     catch (...)     catch (...)
     {     {
     }     }
 } }
  
 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 362 
Line 367 
             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 384 
                 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");
Line 408 
Line 413 
                 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)
             {             {
                 Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,                  Tracer::trace(TRC_THREAD, Tracer::LEVEL4,
                     "ThreadPool::_loop: work func is 0, meaning we should exit.");                     "ThreadPool::_loop: work func is 0, meaning we should exit.");
                 break;                 break;
             }             }
  
             gettimeofday(lastActivityTime, NULL);              Time::gettimeofday(lastActivityTime);
  
             try             try
             {             {
Line 433 
Line 438 
                         e.getMessage());                         e.getMessage());
             }             }
 #if !defined(PEGASUS_OS_LSB) #if !defined(PEGASUS_OS_LSB)
             catch (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("Exception from work in ThreadPool::_loop: ") +
Line 449 
Line 454 
             // 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();
                 }                 }
  
                 Boolean removed = pool->_runningThreads.remove((void *)myself);                  pool->_runningThreads.remove(myself);
                 PEGASUS_ASSERT(removed);                  pool->_idleThreads.insert_front(myself);
   
                 pool->_idleThreads.insert_first(myself);  
             }             }
             catch (...)             catch (...)
             {             {
Line 467 
Line 470 
                 PEGASUS_ASSERT(false);                 PEGASUS_ASSERT(false);
                 pool->_currentThreads--;                 pool->_currentThreads--;
                 PEG_METHOD_EXIT();                 PEG_METHOD_EXIT();
                 return((PEGASUS_THREAD_RETURN)1);                  return((ThreadReturnType)1);
             }             }
         }         }
     }     }
Line 483 
Line 486 
     }     }
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     return((PEGASUS_THREAD_RETURN)0);      return((ThreadReturnType)0);
 } }
  
 Boolean ThreadPool::allocate_and_awaken(  ThreadStatus ThreadPool::allocate_and_awaken(
     void* parm,     void* parm,
     PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL* work)(void *),      ThreadReturnType (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 499 
Line 502 
  
     try     try
     {     {
         if (_dying.value())          if (_dying.get())
         {         {
             Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,             Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                 "ThreadPool::allocate_and_awaken: ThreadPool is dying(1).");                 "ThreadPool::allocate_and_awaken: ThreadPool is dying(1).");
             // ATTN: Error result has not yet been defined              return PEGASUS_THREAD_UNAVAILABLE;
             return true;  
         }         }
         struct timeval start;         struct timeval start;
         gettimeofday(&start, NULL);          Time::gettimeofday(&start);
         Thread* th = 0;         Thread* th = 0;
  
         th = _idleThreads.remove_first();          th = _idleThreads.remove_front();
  
         if (th == 0)         if (th == 0)
         {         {
             if ((_maxThreads == 0) || (_currentThreads < _maxThreads))              if ((_maxThreads == 0) ||
                   (_currentThreads.get() < Uint32(_maxThreads)))
             {             {
                 th = _initializeThread();                 th = _initializeThread();
             }             }
Line 527 
Line 530 
             // necessarily imply that a failure has occurred.  However,             // necessarily imply that a failure has occurred.  However,
             // this label is being used temporarily to help isolate             // this label is being used temporarily to help isolate
             // the cause of client timeout problems.             // the cause of client timeout problems.
   
             Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,             Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                 "ThreadPool::allocate_and_awaken: Insufficient resources: "                 "ThreadPool::allocate_and_awaken: Insufficient resources: "
                     " pool = %s, running threads = %d, idle threads = %d",                     " pool = %s, running threads = %d, idle threads = %d",
                 _key, _runningThreads.count(), _idleThreads.count());                  _key, _runningThreads.size(), _idleThreads.size());
             return false;              return PEGASUS_THREAD_INSUFFICIENT_RESOURCES;
         }         }
  
         // initialize the thread data with the work function and parameters         // initialize the thread data with the work function and parameters
Line 542 
Line 544 
  
         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 *)),
             (void *)work);             (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);
Line 551 
Line 553 
             th->put_tsd("blocking sem", NULL, sizeof(Semaphore *), blocking);             th->put_tsd("blocking sem", NULL, sizeof(Semaphore *), blocking);
  
         // put the thread on the running list         // put the thread on the running list
         _runningThreads.insert_first(th);          _runningThreads.insert_front(th);
  
         // signal the thread's sleep semaphore to awaken it         // signal the thread's sleep semaphore to awaken it
         Semaphore* sleep_sem = (Semaphore *)th->reference_tsd("sleep sem");         Semaphore* sleep_sem = (Semaphore *)th->reference_tsd("sleep sem");
Line 567 
Line 569 
             "ThreadPool::allocate_and_awaken: Operation Failed.");             "ThreadPool::allocate_and_awaken: Operation Failed.");
         PEG_METHOD_EXIT();         PEG_METHOD_EXIT();
         // ATTN: Error result has not yet been defined         // ATTN: Error result has not yet been defined
         return true;          return PEGASUS_THREAD_SETUP_FAILURE;
     }     }
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     return true;      return PEGASUS_THREAD_OK;
 } }
  
 // caller is responsible for only calling this routine during slack periods // caller is responsible for only calling this routine during slack periods
Line 582 
Line 584 
  
     Uint32 numThreadsCleanedUp = 0;     Uint32 numThreadsCleanedUp = 0;
  
     Uint32 numIdleThreads = _idleThreads.count();      Uint32 numIdleThreads = _idleThreads.size();
     for (Uint32 i = 0; i < numIdleThreads; i++)     for (Uint32 i = 0; i < numIdleThreads; i++)
     {     {
         // Do not dip below the minimum thread count         // Do not dip below the minimum thread count
         if (_currentThreads.value() <= (Uint32)_minThreads)          if (_currentThreads.get() <= (Uint32)_minThreads)
         {         {
             break;             break;
         }         }
  
         Thread* thread = _idleThreads.remove_last();          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)
Line 609 
Line 611 
         catch (...)         catch (...)
         {         {
             PEGASUS_ASSERT(false);             PEGASUS_ASSERT(false);
             _idleThreads.insert_last(thread);              _idleThreads.insert_back(thread);
             break;             break;
         }         }
  
Line 625 
Line 627 
         }         }
         else         else
         {         {
             _idleThreads.insert_first(thread);              _idleThreads.insert_front(thread);
         }         }
     }     }
  
Line 641 
Line 643 
     thread->delete_tsd("work func");     thread->delete_tsd("work func");
     thread->put_tsd(     thread->put_tsd(
         "work func", 0,         "work func", 0,
         sizeof(PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *)),          sizeof(ThreadReturnType (PEGASUS_THREAD_CDECL *)(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 670 
Line 672 
  
     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 679 
Line 681 
     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 702 
Line 704 
  
     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);
     // thread will enter _loop() and sleep on sleep_sem until we signal it     // thread will enter _loop() and sleep on sleep_sem until we signal it
  
     if (!th->run())      if (th->run() != PEGASUS_THREAD_OK)
     {     {
                   Tracer::trace(TRC_THREAD, Tracer::LEVEL2,
                           "Could not create thread. Error code is %d.", errno);
         delete th;         delete th;
         return 0;         return 0;
     }     }
     _currentThreads++;     _currentThreads++;
     pegasus_yield();      Threads::yield();
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     return th;     return th;
Line 731 
Line 735 
  
     try     try
     {     {
         _idleThreads.insert_first(th);          _idleThreads.insert_front(th);
     }     }
     catch (...)     catch (...)
     {     {
         Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,         Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
             "ThreadPool::_addToIdleThreadsQueue: _idleThreads.insert_first "              "ThreadPool::_addToIdleThreadsQueue: _idleThreads.insert_front "
                 "failed.");                 "failed.");
     }     }
 } }
  
   // 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.83  
changed lines
  Added in v.1.90.2.4

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2