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

version 1.34, 2003/03/20 15:51: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
   try {     {
    _pools.remove(this);    _pools.remove(this);
    _dying++;    _dying++;
    Thread *th = 0;    Thread *th = 0;
Line 232 
Line 357 
       th = _dead.remove_first();       th = _dead.remove_first();
    }    }
   }   }
   catch(...){}     catch(...)
      {
      }
 } }
  
 // make this static to the class // make this static to the class
Line 240 
Line 367 
 { {
    PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::_loop");    PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::_loop");
  
    Tracer::trace(TRC_THREAD, Tracer::LEVEL4, "ThreadPool::_loop entered");  
    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 267 
Line 399 
    }    }
    catch(IPCException &)    catch(IPCException &)
    {    {
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "IPCException Caught - EXITING");  
       PEG_METHOD_EXIT();       PEG_METHOD_EXIT();
       myself->exit_self(0);       myself->exit_self(0);
    }    }
    catch(...)    catch(...)
    {    {
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "Unknown  Exception Caught - EXITING");  
       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)
    {    {
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "NULL Semaphore  - EXITING");  
       PEG_METHOD_EXIT();       PEG_METHOD_EXIT();
       throw NullPointer();       throw NullPointer();
    }    }
  
    while(pool->_dying < 1)    while(pool->_dying < 1)
    {    {
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "ThreadPool::_loop - waiting on semaphore");  
       sleep_sem->wait();       sleep_sem->wait();
       Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                     "ThreadPool::_loop - awakened from semaphore");  
       // 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 316 
Line 438 
       }       }
       catch(IPCException &)       catch(IPCException &)
       {       {
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "IPCException Caught - EXITING");  
          PEG_METHOD_EXIT();          PEG_METHOD_EXIT();
          myself->exit_self(0);          myself->exit_self(0);
       }       }
  
       if(_work == 0)       if(_work == 0)
       {       {
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "NULL work pointer - EXITING");  
          PEG_METHOD_EXIT();          PEG_METHOD_EXIT();
          throw NullPointer();          throw NullPointer();
       }       }
Line 333 
Line 451 
       if(_work ==       if(_work ==
          (PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *)) &_undertaker)          (PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *)) &_undertaker)
       {       {
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "Calling the Undertaker");  
          _work(parm);          _work(parm);
       }       }
  
       gettimeofday(deadlock_timer, NULL);       gettimeofday(deadlock_timer, NULL);
       try       try
       {       {
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "ThreadPool::_loop - calling work routine");  
          _work(parm);          _work(parm);
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "ThreadPool::_loop - returned from work routine");  
       }       }
       catch(...)       catch(...)
       {       {
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "Unknown  Exception Caught - EXITING");  
          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 365 
Line 476 
       }       }
       catch(IPCException &)       catch(IPCException &)
       {       {
          Tracer::trace(__FILE__, __LINE__, TRC_THREAD, Tracer::LEVEL4,  
                        "IPCException Caught - EXITING");  
          PEG_METHOD_EXIT();          PEG_METHOD_EXIT();
          myself->exit_self(0);          myself->exit_self(0);
       }       }
Line 403 
Line 512 
           th = _init_thread();           th = _init_thread();
           continue;           continue;
         }         }
         pegasus_yield();
       pegasus_sleep(1);  
       th = _pool.remove_first();       th = _pool.remove_first();
    }    }
  
Line 628 
Line 736 
    struct timeval now, finish, remaining;    struct timeval now, finish, remaining;
    Uint32 usec;    Uint32 usec;
    pegasus_gettimeofday(&now);    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 676 
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 685 
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 703 
Line 815 
 } }
  
  
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END
  


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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2