(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.32 and 1.44

version 1.32, 2003/03/18 22:35:27 version 1.44, 2003/09/25 12:01:22
Line 44 
Line 44 
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
   
 void thread_data::default_delete(void * data) void thread_data::default_delete(void * data)
 { {
    if( data != NULL)    if( data != NULL)
       ::operator delete(data);       ::operator delete(data);
 } }
  
   // l10n start
   void language_delete(void * data)
   {
      if( data != NULL)
      {
         AcceptLanguages * al = static_cast<AcceptLanguages *>(data);
         delete al;
      }
   }
   // l10n end
   
 Boolean Thread::_signals_blocked = false; Boolean Thread::_signals_blocked = false;
   // l10n
   PEGASUS_THREAD_KEY_TYPE Thread::_platform_thread_key;
   Boolean Thread::_key_initialized = false;
   Boolean Thread::_key_error = false;
   
  
 // for non-native implementations // for non-native implementations
 #ifndef PEGASUS_THREAD_CLEANUP_NATIVE #ifndef PEGASUS_THREAD_CLEANUP_NATIVE
Line 115 
Line 132 
  
 #endif #endif
  
   // l10n start
   Sint8 Thread::initializeKey()
   {
      PEG_METHOD_ENTER(TRC_THREAD, "Thread::initializeKey");
      if (!Thread::_key_initialized)
      {
           if (Thread::_key_error)
           {
                   Tracer::trace(TRC_THREAD, Tracer::LEVEL4,
                             "Thread: ERROR - thread key error");
                   return -1;
           }
   
           if (pegasus_key_create(&Thread::_platform_thread_key) == 0)
           {
                   Tracer::trace(TRC_THREAD, Tracer::LEVEL4,
                             "Thread: able to create a thread key");
                   Thread::_key_initialized = true;
           }
           else
           {
                   Tracer::trace(TRC_THREAD, Tracer::LEVEL4,
                             "Thread: ERROR - unable to create a thread key");
                   Thread::_key_error = true;
                   return -1;
           }
      }
   
      PEG_METHOD_EXIT();
      return 0;
   }
   
   Thread * Thread::getCurrent()
   {
       PEG_METHOD_ENTER(TRC_THREAD, "Thread::getCurrent");
       if (Thread::initializeKey() != 0)
       {
           return NULL;
       }
       PEG_METHOD_EXIT();
       return (Thread *)pegasus_get_thread_specific(_platform_thread_key);
   }
   
   void Thread::setCurrent(Thread * thrd)
   {
      PEG_METHOD_ENTER(TRC_THREAD, "Thread::setCurrent");
      if (Thread::initializeKey() == 0)
      {
           if (pegasus_set_thread_specific(Thread::_platform_thread_key,
                                                                    (void *) thrd) == 0)
           {
                   Tracer::trace(TRC_THREAD, Tracer::LEVEL4,
                             "Successful set Thread * into thread specific storage");
           }
           else
           {
                   Tracer::trace(TRC_THREAD, Tracer::LEVEL4,
                             "ERROR: got error setting Thread * into thread specific storage");
           }
      }
      PEG_METHOD_EXIT();
   }
   
   AcceptLanguages * Thread::getLanguages()
   {
       PEG_METHOD_ENTER(TRC_THREAD, "Thread::getLanguages");
   
           Thread * curThrd = Thread::getCurrent();
           if (curThrd == NULL)
                   return NULL;
           AcceptLanguages * acceptLangs =
                    (AcceptLanguages *)curThrd->reference_tsd("acceptLanguages");
           curThrd->dereference_tsd();
       PEG_METHOD_EXIT();
           return acceptLangs;
   }
   
   void Thread::setLanguages(AcceptLanguages *langs) //l10n
   {
      PEG_METHOD_ENTER(TRC_THREAD, "Thread::setLanguages");
   
      Thread * currentThrd = Thread::getCurrent();
      if (currentThrd != NULL)
      {
                   // deletes the old tsd and creates a new one
                   currentThrd->put_tsd("acceptLanguages",
                           language_delete,
                           sizeof(AcceptLanguages *),
                           langs);
      }
   
      PEG_METHOD_EXIT();
   }
   
   void Thread::clearLanguages() //l10n
   {
      PEG_METHOD_ENTER(TRC_THREAD, "Thread::clearLanguages");
   
      Thread * currentThrd = Thread::getCurrent();
      if (currentThrd != NULL)
      {
                   // deletes the old tsd
                   currentThrd->delete_tsd("acceptLanguages");
      }
   
      PEG_METHOD_EXIT();
   }
   // l10n end
   
 DQueue<ThreadPool> ThreadPool::_pools(true); DQueue<ThreadPool> ThreadPool::_pools(true);
  
  
Line 176 
Line 302 
       _link_pool(_init_thread());       _link_pool(_init_thread());
    }    }
    _pools.insert_last(this);    _pools.insert_last(this);
   
 } }
  
  
  
 ThreadPool::~ThreadPool(void) ThreadPool::~ThreadPool(void)
 { {
      try
      {
    _pools.remove(this);    _pools.remove(this);
    _dying++;    _dying++;
    Thread *th = 0;    Thread *th = 0;
Line 230 
Line 356 
       delete th;       delete th;
       th = _dead.remove_first();       th = _dead.remove_first();
    }    }
      }
      catch(...)
      {
      }
 } }
  
 // make this static to the class // make this static to the class
Line 238 
Line 367 
 { {
    PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::_loop");    PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::_loop");
  
 #if defined(PEGASUS_DEBUG)  
    char trace_buf[24];  
    snprintf(trace_buf, 23, "%d", (Uint32)pegasus_thread_self());  
    Tracer::trace(TRC_THREAD, Tracer::LEVEL4, "ThreadPool::_loop entered by %s", trace_buf);  
 #endif  
   
   
    Thread *myself = (Thread *)parm;    Thread *myself = (Thread *)parm;
    if(myself == 0)    if(myself == 0)
    {    {
       PEG_METHOD_EXIT();       PEG_METHOD_EXIT();
       throw NullPointer();       throw NullPointer();
    }    }
   
   // l10n
      // Set myself into thread specific storage
      // This will allow code to get its own Thread
      Thread::setCurrent(myself);
   
    ThreadPool *pool = (ThreadPool *)myself->get_parm();    ThreadPool *pool = (ThreadPool *)myself->get_parm();
    if(pool == 0 )    if(pool == 0 )
    {    {
Line 271 
Line 399 
    }    }
    catch(IPCException &)    catch(IPCException &)
    {    {
 #if defined(PEGASUS_DEBUG)  
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "%s: IPCException Caught - EXITING", trace_buf);  
 #endif  
       PEG_METHOD_EXIT();       PEG_METHOD_EXIT();
       myself->exit_self(0);       myself->exit_self(0);
    }    }
    catch(...)    catch(...)
    {    {
 #if defined(PEGASUS_DEBUG)  
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "%s: Unknown  Exception Caught - EXITING", trace_buf);  
 #endif  
       PEG_METHOD_EXIT();       PEG_METHOD_EXIT();
       myself->exit_self(0);       myself->exit_self(0);
    }    }
  
    if(sleep_sem == 0 || deadlock_timer == 0)    if(sleep_sem == 0 || deadlock_timer == 0)
    {    {
 #if defined(PEGASUS_DEBUG)  
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "%s: NULL Semaphore  - EXITING", trace_buf);  
 #endif  
       PEG_METHOD_EXIT();       PEG_METHOD_EXIT();
       throw NullPointer();       throw NullPointer();
    }    }
  
    while(pool->_dying < 1)    while(pool->_dying < 1)
    {    {
 #if defined(PEGASUS_DEBUG)  
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "%s: ThreadPool::_loop - waiting on semaphore", trace_buf);  
 #endif  
       sleep_sem->wait();       sleep_sem->wait();
 #if defined(PEGASUS_DEBUG)  
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "%s: ThreadPool::_loop - awakened from semaphore", trace_buf);  
 #endif  
       // when we awaken we reside on the running queue, not the pool queue       // when we awaken we reside on the running queue, not the pool queue
       if(pool->_dying > 0)       if(pool->_dying > 0)
          break;          break;
  
   
       PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *_work)(void *) = 0;       PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *_work)(void *) = 0;
       void *parm = 0;       void *parm = 0;
  
Line 330 
Line 438 
       }       }
       catch(IPCException &)       catch(IPCException &)
       {       {
 #if defined(PEGASUS_DEBUG)  
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "%s: IPCException Caught - EXITING", trace_buf);  
 #endif  
          PEG_METHOD_EXIT();          PEG_METHOD_EXIT();
          myself->exit_self(0);          myself->exit_self(0);
       }       }
  
       if(_work == 0)       if(_work == 0)
       {       {
 #if defined(PEGASUS_DEBUG)  
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "%s: NULL work pointer - EXITING", trace_buf);  
 #endif  
          PEG_METHOD_EXIT();          PEG_METHOD_EXIT();
          throw NullPointer();          throw NullPointer();
       }       }
Line 351 
Line 451 
       if(_work ==       if(_work ==
          (PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *)) &_undertaker)          (PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *)) &_undertaker)
       {       {
 #if defined(PEGASUS_DEBUG)  
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "%s: Calling the Undertaker", trace_buf);  
 #endif  
          _work(parm);          _work(parm);
       }       }
  
       gettimeofday(deadlock_timer, NULL);       gettimeofday(deadlock_timer, NULL);
       try       try
       {       {
 #if defined(PEGASUS_DEBUG)  
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "%s: ThreadPool::_loop - calling work routine", trace_buf);  
 #endif  
          _work(parm);          _work(parm);
 #if defined(PEGASUS_DEBUG)  
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "%s: ThreadPool::_loop - returned from work routine", trace_buf);  
 #endif  
       }       }
       catch(...)       catch(...)
       {       {
 #if defined(PEGASUS_DEBUG)  
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "%s: Unknown  Exception Caught - EXITING");  
 #endif  
          gettimeofday(deadlock_timer, NULL);          gettimeofday(deadlock_timer, NULL);
       }       }
   
       gettimeofday(deadlock_timer, NULL);       gettimeofday(deadlock_timer, NULL);
       if( blocking_sem != 0 )       if( blocking_sem != 0 )
          blocking_sem->signal();          blocking_sem->signal();
Line 391 
Line 476 
       }       }
       catch(IPCException &)       catch(IPCException &)
       {       {
 #if defined(PEGASUS_DEBUG)  
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "%s: IPCException Caught - EXITING", trace_buf);  
 #endif  
          PEG_METHOD_EXIT();          PEG_METHOD_EXIT();
          myself->exit_self(0);          myself->exit_self(0);
       }       }
Line 489 
Line 570 
    // first go thread the dead q and clean it up as much as possible    // first go thread the dead q and clean it up as much as possible
    while(_dead.count() > 0)    while(_dead.count() > 0)
    {    {
         Tracer::trace(TRC_THREAD, Tracer::LEVEL4, "ThreadPool:: removing and joining dead thread");
 #if !defined(PEGASUS_PLATFORM_HPUX_ACC) && !defined(PEGASUS_PLATFORM_LINUX_IA64_GNU)  
       PEGASUS_STD(cout) << "ThreadPool:: removing and joining dead thread" << PEGASUS_STD(endl);  
 #endif  
       Thread *dead = _dead.remove_first();       Thread *dead = _dead.remove_first();
       if(dead == 0)       if(dead == 0)
          throw NullPointer();          throw NullPointer();
Line 627 
Line 705 
                   else                   else
                   {                   {
                      // deadlocked threads                      // deadlocked threads
 #if !defined(PEGASUS_PLATFORM_HPUX_ACC) && !defined(PEGASUS_PLATFORM_LINUX_IA64_GNU)                       Tracer::trace(TRC_THREAD, Tracer::LEVEL4, "Killing a deadlocked thread");
                      PEGASUS_STD(cout) << "Killing a deadlocked thread" << PEGASUS_STD(endl);  
 #endif  
                      th->cancel();                      th->cancel();
                      delete th;                      delete th;
                   }                   }
Line 659 
Line 735 
  
    struct timeval now, finish, remaining;    struct timeval now, finish, remaining;
    Uint32 usec;    Uint32 usec;
    gettimeofday(&now, NULL);     pegasus_gettimeofday(&now);
      /* remove valgrind error */
      pegasus_gettimeofday(&remaining);
   
  
    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 708 
Line 787 
  
  Thread *ThreadPool::_init_thread(void) throw(IPCException)  Thread *ThreadPool::_init_thread(void) throw(IPCException)
 { {
    PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::_init_thread");  
    Thread *th = (Thread *) new Thread(_loop, this, false);    Thread *th = (Thread *) new Thread(_loop, this, false);
    // allocate a sleep semaphore and pass it in the thread context    // allocate a sleep semaphore and pass it in the thread context
    // initial count is zero, loop function will sleep until    // initial count is zero, loop function will sleep until
Line 717 
Line 795 
    th->put_tsd("sleep sem", &_sleep_sem_del, sizeof(Semaphore), (void *)sleep_sem);    th->put_tsd("sleep sem", &_sleep_sem_del, sizeof(Semaphore), (void *)sleep_sem);
  
    struct timeval *dldt = (struct timeval *) ::operator new(sizeof(struct timeval));    struct timeval *dldt = (struct timeval *) ::operator new(sizeof(struct timeval));
      pegasus_gettimeofday(dldt);
   
    th->put_tsd("deadlock timer", thread_data::default_delete, sizeof(struct timeval), (void *)dldt);    th->put_tsd("deadlock timer", thread_data::default_delete, sizeof(struct timeval), (void *)dldt);
    // thread will enter _loop(void *) and sleep on sleep_sem until we signal it    // thread will enter _loop(void *) and sleep on sleep_sem until we signal it
   
    th->run();    th->run();
    _current_threads++;    _current_threads++;
    pegasus_yield();    pegasus_yield();
    PEG_METHOD_EXIT();  
  
    return th;    return th;
 } }
Line 735 
Line 815 
 } }
  
  
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END
  


Legend:
Removed from v.1.32  
changed lines
  Added in v.1.44

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2