(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.63 and 1.69

version 1.63, 2008/09/17 18:47:22 version 1.69, 2009/08/13 13:13:07
Line 1 
Line 1 
 //%2006////////////////////////////////////////////////////////////////////////  //%LICENSE////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development  // Licensed to The Open Group (TOG) under one or more contributor license
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.  // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;  // this work for additional information regarding copyright ownership.
 // IBM Corp.; EMC Corporation, The Open Group.  // Each contributor licenses this file to you under the OpenPegasus Open
 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;  // Source License; you may not use this file except in compliance with the
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.  // License.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;  //
 // EMC Corporation; VERITAS Software Corporation; The Open Group.  // Permission is hereby granted, free of charge, to any person obtaining a
 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;  // copy of this software and associated documentation files (the "Software"),
 // EMC Corporation; Symantec Corporation; The Open Group.  // to deal in the Software without restriction, including without limitation
 //  // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 // Permission is hereby granted, free of charge, to any person obtaining a copy  // and/or sell copies of the Software, and to permit persons to whom the
 // of this software and associated documentation files (the "Software"), to  // Software is furnished to do so, subject to the following conditions:
 // deal in the Software without restriction, including without limitation the  //
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  // The above copyright notice and this permission notice shall be included
 // sell copies of the Software, and to permit persons to whom the Software is  // in all copies or substantial portions of the Software.
 // furnished to do so, subject to the following conditions:  //
 //  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT  // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN  // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
 // //
 //==============================================================================  //////////////////////////////////////////////////////////////////////////
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
Line 81 
Line 79 
  
 /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
  
 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 145 
Line 168 
     */     */
     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 160 
Line 181 
         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.
Line 174 
Line 200 
      */      */
     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;
Line 184 
Line 210 
     // @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);
     }     }
  
     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 255 
Line 268 
     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 290 
Line 303 
  
     void cleanup_pop(Boolean execute = true);     void cleanup_pop(Boolean execute = true);
  
     // create and initialize a tsd  
     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 !!!!
     inline void *reference_tsd(const char* key)      void* reference_tsd(TSD_Key key)
     {  
         _tsd.lock();  
         thread_data *tsd = _tsd.find(thread_data::equal, key);  
         if (tsd != NULL)  
             return (void *) (tsd->_data);  
         else  
             return NULL;  
     }  
   
     inline Boolean try_reference_tsd(const char *key, void** data)  
     {  
         if (!_tsd.try_lock())  
         {         {
             return false;          if (_tsd[key])
         }              return _tsd[key]->get_data();
         thread_data *tsd = _tsd.find(thread_data::equal, key);  
         if (tsd != NULL)  
             *data = (void*) (tsd->_data);  
         else         else
             *data = NULL;              return 0;
         return true;  
     }     }
  
   
     // 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() !!!
     inline void dereference_tsd()      void dereference_tsd()
     {     {
         _tsd.unlock();  
     }     }
  
     // delete the tsd associated with the key     // delete the tsd associated with the key
     inline void delete_tsd(const char *key)      void delete_tsd(TSD_Key key)
     {     {
         AutoPtr < thread_data > tsd(_tsd.remove(thread_data::equal, key));          thread_data* tsd;
   
           tsd = _tsd[key];
           _tsd[key] = 0;
   
           if (tsd)
               delete tsd;
     }     }
  
     inline void empty_tsd()      void empty_tsd()
     {     {
         _tsd.clear();          thread_data* data[TSD_COUNT];
   
           memcpy(data, _tsd, sizeof(_tsd));
           memset(_tsd, 0, sizeof(_tsd));
   
           for (size_t i = 0; i < TSD_COUNT; i++)
           {
               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
     void put_tsd(     void put_tsd(
         const char* key,          TSD_Key key,
         void (*delete_func) (void *),         void (*delete_func) (void *),
         Uint32 size,         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));  
         tsd.reset();          thread_data* old;
         AutoPtr<thread_data> ntsd(new thread_data(key));  
         ntsd->put_data(delete_func, size, value);          old = _tsd[key];
         _tsd.insert_front(ntsd.get());          _tsd[key] = tsd;
         ntsd.release();  
           if (old)
               delete old;
     }     }
  
     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 375 
Line 380 
         return _handle;         return _handle;
     }     }
  
       Boolean isDetached()
       {
           return _is_detached;
       }
   
     void detach();     void detach();
  
     //     //
Line 417 
Line 427 
  
     static Sint8 initializeKey();     static Sint8 initializeKey();
  
     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 _cancelled;     Boolean _cancelled;
Line 433 
Line 436 
  
     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;


Legend:
Removed from v.1.63  
changed lines
  Added in v.1.69

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2