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

Diff for /pegasus/src/Pegasus/Common/Thread.h between version 1.57.2.6 and 1.65

version 1.57.2.6, 2006/07/29 15:54:07 version 1.65, 2008/11/13 22:15:03
Line 29 
Line 29 
 // //
 //============================================================================== //==============================================================================
 // //
 // Author: Mike Day (mdday@us.ibm.com)  
 //  
 // Modified By: Markus Mueller  
 //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)  
 //              Amit K Arora, IBM (amita@in.ibm.com) for PEP#101  
 //              David Dillard, VERITAS Software Corp.  
 //                  (david.dillard@veritas.com)  
 //              Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)  
 //              Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2393  
 //  
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #ifndef Pegasus_Thread_h #ifndef Pegasus_Thread_h
Line 91 
Line 81 
  
 /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
  
 class PEGASUS_COMMON_LINKAGE thread_data : public Linkable  enum TSD_Key
   {
       TSD_ACCEPT_LANGUAGES,
       TSD_SLEEP_SEM,
       TSD_LAST_ACTIVITY_TIME,
       TSD_WORK_FUNC,
       TSD_WORK_PARM,
       TSD_BLOCKING_SEM,
       TSD_CIMOM_HANDLE_CONTENT_LANGUAGES,
       TSD_RESERVED_1,
       TSD_RESERVED_2,
       TSD_RESERVED_3,
       TSD_RESERVED_4,
       TSD_RESERVED_5,
       TSD_RESERVED_6,
       TSD_RESERVED_7,
       TSD_RESERVED_8,
       // Add new TSD keys before this line.
       TSD_COUNT
   };
   
   class thread_data
 { {
       /**
        * This class is NOT build thread-safe.
        * The Caller(user) of this class has to ensure there is no collision
        * taking place.
        *
        * There is no mechanism in place to protect threads from manipulating
        * the same thread-specific storage at one time.
        * Make sure the possibility for a parallel access to the same
        * threads-specific data from multiple threads cannot arise.
        *
        * In OpenPegasus this class is used in the ThreadPool
        *        - on initialisation and creation of threads owned by ThreadPool
        *        - on threads that are idle inside the ThreadPool
        *        - on the ThreadPools main thread (the thread which the ThreadPool
        *          runs in)
        * In OpenPegasus this class is used in the
        * ClientCIMOMHandleRep and InternalCIMOMHandleRep
        *        - on the current active Thread which belongs to that CIMOMHandle
        *
        */
 public: public:
  
     static void default_delete(void *data);      static void default_delete(void *data)
       {
           if (data)
               ::operator  delete(data);
       }
  
     thread_data(const char *key) : _delete_func(NULL), _data(NULL), _size(0)      thread_data(TSD_Key key) : _delete_func(0), _data(0), _size(0), _key(key)
     {     {
         PEGASUS_ASSERT(key != NULL);  
         size_t keysize = strlen(key);  
         _key.reset(new char[keysize + 1]);  
         memcpy(_key.get(), key, keysize);  
         _key.get()[keysize] = 0x00;  
     }     }
  
     thread_data(const char *key, size_t size) :      thread_data(TSD_Key key, size_t size) :
         _delete_func(default_delete), _size(size)          _delete_func(default_delete), _size(size), _key(key)
     {     {
         PEGASUS_ASSERT(key != NULL);  
         size_t keysize = strlen(key);  
         _key.reset(new char[keysize + 1]);  
         memcpy(_key.get(), key, keysize);  
         _key.get()[keysize] = 0x00;  
         _data =::operator  new(_size);         _data =::operator  new(_size);
     }     }
  
     thread_data(const char *key, size_t size, void *data) :      thread_data(TSD_Key key, size_t size, void* data)
         _delete_func(default_delete), _size(size)          : _delete_func(default_delete), _size(size), _key(key)
     {     {
         PEGASUS_ASSERT(key != NULL);  
         PEGASUS_ASSERT(data != NULL);  
         size_t keysize = strlen(key);  
   
         _key.reset(new char[keysize + 1]);  
         memcpy(_key.get(), key, keysize);  
         _key.get()[keysize] = 0x00;  
         _data =::operator  new(_size);         _data =::operator  new(_size);
         memcpy(_data, data, size);         memcpy(_data, data, size);
     }     }
  
     ~thread_data()     ~thread_data()
     {     {
         if (_data != NULL)          if (_data && _delete_func)
             if (_delete_func != NULL)              (*_delete_func)(_data);
             {  
                 _delete_func(_data);  
             }  
     }     }
  
     /**     /**
Line 155 
Line 170 
     */     */
     void put_data(void (*del) (void *), size_t size, void *data)     void put_data(void (*del) (void *), size_t size, void *data)
     {     {
         if (_data != NULL)          if (_data && _delete_func)
             if (_delete_func != NULL)              (*_delete_func)(_data);
                 _delete_func(_data);  
  
         _delete_func = del;         _delete_func = del;
         _data = data;         _data = data;
         _size = size;         _size = size;
         return;  
     }     }
  
     size_t get_size()     size_t get_size()
Line 170 
Line 183 
         return _size;         return _size;
     }     }
  
       void* get_data()
       {
           return _data;
       }
   
       /**       /**
        * This function is used to retrieve data from the          This function is used to retrieve data from the
        * TSD, the thread specific data.          TSD, the thread specific data.
        *  
        * Be aware that there is NOTHING in place to stop          Be aware that there is NOTHING in place to stop
        * other users of the thread to change the data you          other users of the thread to change the data you
        * get from this function.          get from this function.
        *  
        * You, the developer has to make sure that there are          You, the developer has to make sure that there are
        * no situations in which this can arise (ie, have a          no situations in which this can arise (ie, have a
        * lock for the function which manipulates the TSD.          lock for the function which manipulates the TSD.
        */        */
     void get_data(void **data, size_t * size)     void get_data(void **data, size_t * size)
     {     {
         if (data == NULL || size == NULL)          if (data == 0 || size == 0)
             throw NullPointer();             throw NullPointer();
  
         *data = _data;         *data = _data;
         *size = _size;         *size = _size;
         return;  
   
     }     }
  
     // @exception NullPointer     // @exception NullPointer
     void copy_data(void **buf, size_t * size)     void copy_data(void **buf, size_t * size)
     {     {
         if ((buf == NULL) || (size == NULL))          if ((buf == 0) || (size == 0))
             throw NullPointer();             throw NullPointer();
   
         *buf =::operator  new(_size);         *buf =::operator  new(_size);
         *size = _size;         *size = _size;
         memcpy(*buf, _data, _size);         memcpy(*buf, _data, _size);
         return;  
     }  
   
     inline Boolean operator==(const void *key) const  
     {  
         if (!strcmp(_key.get(), reinterpret_cast < const char *>(key)))  
               return (true);  
           return (false);  
     }     }
  
     inline Boolean operator==(const thread_data & b) const  
     {  
         return (operator==(b._key.get()));  
     }  
   
     static bool equal(const thread_data * node, const void *key)  
     {  
         return ((thread_data *) node)->operator==(key);  
     }  
  
   private:   private:
     void (*_delete_func) (void *data);  
     thread_data();     thread_data();
       thread_data(const thread_data& x);
       thread_data& operator=(const thread_data& x);
   
       void (*_delete_func)(void*);
     void *_data;     void *_data;
     size_t _size;     size_t _size;
     AutoArrayPtr < char >_key;      TSD_Key _key;
   
     friend class Thread;  
 }; };
  
  
Line 250 
Line 252 
 { {
   public:   public:
  
     Thread(ThreadReturnType(PEGASUS_THREAD_CDECL * start) (void *),      Thread(
            void *parameter, Boolean detached);          ThreadReturnType(PEGASUS_THREAD_CDECL* start) (void*),
           void* parameter,
           Boolean detached);
  
      ~Thread();      ~Thread();
  
Line 266 
Line 270 
     ThreadStatus run();     ThreadStatus run();
  
     // get the user parameter     // get the user parameter
     inline void *get_parm()      void *get_parm()
     {     {
         return _thread_parm;         return _thread_parm;
     }     }
Line 276 
Line 280 
     // when it should die.     // when it should die.
     void cancel();     void cancel();
  
     // cancel if there is a pending cancellation request  
     void test_cancel();  
   
     Boolean is_cancelled();  
   
     // for user-level threads - put the calling thread     // for user-level threads - put the calling thread
     // to sleep and jump to the thread scheduler.     // to sleep and jump to the thread scheduler.
     // platforms with preemptive scheduling and native threads     // platforms with preemptive scheduling and native threads
Line 291 
Line 290 
  
     void thread_switch();     void thread_switch();
  
 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)  
     // suspend this thread  
     void suspend();  
   
     // resume this thread  
     void resume();  
 #endif  
   
     static void sleep(Uint32 msec);     static void sleep(Uint32 msec);
  
     // block the calling thread until this thread terminates     // block the calling thread until this thread terminates
     void join();     void join();
     void thread_init();  
  
     // thread routine needs to call this function when     // thread routine needs to call this function when
     // it is ready to exit     // it is ready to exit
Line 311 
Line 301 
  
     // stack of functions to be called when thread terminates     // stack of functions to be called when thread terminates
     // will be called last in first out (LIFO)     // will be called last in first out (LIFO)
     // @exception IPCException  
     void cleanup_push(void (*routine) (void *), void *parm);     void cleanup_push(void (*routine) (void *), void *parm);
  
     // @exception IPCException  
     void cleanup_pop(Boolean execute = true);     void cleanup_pop(Boolean execute = true);
  
     // create and initialize a tsd  
     // @exception IPCException  
     inline void create_tsd(const char *key, int size, void *buffer)  
     {  
         AutoPtr < thread_data > tsd(new thread_data(key, size, buffer));  
         _tsd.insert_front(tsd.get());  
         tsd.release();  
     }  
   
     // get the buffer associated with the key     // get the buffer associated with the key
     // NOTE: this call leaves the tsd LOCKED !!!!     // NOTE: this call leaves the tsd LOCKED !!!!
     // @exception IPCException      void* reference_tsd(TSD_Key key)
     inline void *reference_tsd(const char *key)  
     {  
         _tsd.lock();  
         thread_data *tsd = _tsd.find(thread_data::equal, key);  
         if (tsd != NULL)  
             return ((void *) (tsd->_data));  
         else  
             return (NULL);  
     }  
   
     // @exception IPCException  
     inline void *try_reference_tsd(const char *key)  
     {     {
         _tsd.try_lock();          if (_tsd[key])
         thread_data *tsd = _tsd.find(thread_data::equal, key);              return _tsd[key]->get_data();
         if (tsd != NULL)  
             return ((void *) (tsd->_data));  
         else         else
             return (NULL);              return 0;
     }     }
  
   
     // release the lock held on the tsd     // release the lock held on the tsd
     // NOTE: assumes a corresponding and prior call to reference_tsd() !!!     // NOTE: assumes a corresponding and prior call to reference_tsd() !!!
     // @exception IPCException      void dereference_tsd()
     inline void dereference_tsd()  
     {     {
         _tsd.unlock();  
     }     }
  
     // delete the tsd associated with the key     // delete the tsd associated with the key
     // @exception IPCException      void delete_tsd(TSD_Key key)
     inline void delete_tsd(const char *key)  
     {     {
         AutoPtr < thread_data > tsd(_tsd.remove(thread_data::equal, key));          thread_data* tsd;
   
           tsd = _tsd[key];
           _tsd[key] = 0;
   
           if (tsd)
               delete tsd;
     }     }
  
     // @exception IPCException      void empty_tsd()
     inline void empty_tsd()      {
           thread_data* data[TSD_COUNT];
   
           memcpy(data, _tsd, sizeof(_tsd));
           memset(_tsd, 0, sizeof(_tsd));
   
           for (size_t i = 0; i < TSD_COUNT; i++)
     {     {
         _tsd.clear();              if (data[i])
                   delete data[i];
           }
     }     }
  
     // create or re-initialize tsd associated with the key     // create or re-initialize tsd associated with the key
     // if the tsd already exists, delete the existing buffer     // if the tsd already exists, delete the existing buffer
     // @exception IPCException      void put_tsd(
     void put_tsd(const char *key, void (*delete_func) (void *), Uint32 size,          TSD_Key key,
           void (*delete_func)(void*),
           Uint32 size,
                  void *value)                  void *value)
     {     {
         PEGASUS_ASSERT(key != NULL);          thread_data* tsd = new thread_data(key);
         AutoPtr < thread_data > tsd;          tsd->put_data(delete_func, size, value);
         tsd.reset(_tsd.remove(thread_data::equal, key));        // may throw  
                                                                 // an IPC          thread_data* old;
                                                                 // exception  
         tsd.reset();          old = _tsd[key];
         AutoPtr < thread_data > ntsd(new thread_data(key));          _tsd[key] = tsd;
         ntsd->put_data(delete_func, size, value);  
         try          if (old)
         {              delete old;
             _tsd.insert_front(ntsd.get());  
         }  
         catch(IPCException & e)  
         {  
             e = e;  
             throw;  
         }  
         ntsd.release();  
     }     }
     inline ThreadReturnType get_exit()  
       ThreadReturnType get_exit()
     {     {
         return _exit_code;         return _exit_code;
     }     }
     inline ThreadType self()  
       ThreadType self()
     {     {
         return Threads::self();         return Threads::self();
     }     }
Line 418 
Line 389 
     // Note: this may return NULL if no Thread object is associated     // Note: this may return NULL if no Thread object is associated
     // with the caller's thread.     // with the caller's thread.
     //     //
     static Thread *getCurrent();        // l10n      static Thread *getCurrent();
  
     //     //
     // Sets the Thread object associated with the caller's thread.     // Sets the Thread object associated with the caller's thread.
     // Note: the Thread object must be placed on the heap.     // Note: the Thread object must be placed on the heap.
     //     //
     static void setCurrent(Thread * thrd);      // l10n      static void setCurrent(Thread* thrd);
  
     //     //
     // Gets the AcceptLanguageList object associated with the caller's     // Gets the AcceptLanguageList object associated with the caller's
Line 432 
Line 403 
     // Note: this may return NULL if no Thread object, or no     // Note: this may return NULL if no Thread object, or no
     // AcceptLanguageList object, is associated with the caller's thread.     // AcceptLanguageList object, is associated with the caller's thread.
     //     //
     static AcceptLanguageList *getLanguages();  // l10n      static AcceptLanguageList* getLanguages();
  
     //     //
     // Sets the AcceptLanguageList object associated with the caller's     // Sets the AcceptLanguageList object associated with the caller's
     // Thread.     // Thread.
     // Note: a Thread object must have been previously associated with     // Note: a Thread object must have been previously associated with
     // the caller's thread.     // the caller's thread.
     // Note: the AcceptLanguageList object must be placed on the heap.  
     //     //
     static void setLanguages(AcceptLanguageList * langs);       // l10n      static void setLanguages(const AcceptLanguageList& langs);
  
     //     //
     // Removes the AcceptLanguageList object associated with the caller's     // Removes the AcceptLanguageList object associated with the caller's
     // Thread.     // Thread.
     //     //
     static void clearLanguages();       // l10n      static void clearLanguages();
  
   private:   private:
     Thread();     Thread();
  
     static Sint8 initializeKey();       // l10n      static Sint8 initializeKey();
  
     // @exception IPCException  
     inline void create_tsd(const char *key)  
     {  
         AutoPtr < thread_data > tsd(new thread_data(key));  
         _tsd.insert_front(tsd.get());  
         tsd.release();  
     }  
     ThreadHandle _handle;     ThreadHandle _handle;
     Boolean _is_detached;     Boolean _is_detached;
     Boolean _cancel_enabled;  
     Boolean _cancelled;     Boolean _cancelled;
  
     // always pass this * as the void * parameter to the thread     // always pass this * as the void * parameter to the thread
Line 471 
Line 433 
  
     ThreadReturnType(PEGASUS_THREAD_CDECL * _start) (void *);     ThreadReturnType(PEGASUS_THREAD_CDECL * _start) (void *);
     List < cleanup_handler, Mutex > _cleanup;     List < cleanup_handler, Mutex > _cleanup;
     List < thread_data, Mutex > _tsd;      thread_data* _tsd[TSD_COUNT];
  
     void *_thread_parm;     void *_thread_parm;
     ThreadReturnType _exit_code;     ThreadReturnType _exit_code;
     static Boolean _signals_blocked;     static Boolean _signals_blocked;
     static TSDKeyType _platform_thread_key;     // l10n      static TSDKeyType _platform_thread_key;
     static Boolean _key_initialized;    // l10n      static Boolean _key_initialized;
     static Boolean _key_error;  // l10n      static Boolean _key_error;
 }; };
  
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.57.2.6  
changed lines
  Added in v.1.65

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2