(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.91 and 1.113

version 1.91, 2006/08/09 21:12:42 version 1.113, 2013/04/25 13:00:21
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.  
 // //
 //==============================================================================  //////////////////////////////////////////////////////////////////////////
 //  
 // Author: Mike Day (mdday@us.ibm.com)  
 //  
 // Modified By: Rudy Schuet (rudy.schuet@compaq.com) 11/12/01  
 //              added nsk platform support  
 //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)  
 //              Amit K Arora, IBM (amita@in.ibm.com) for PEP#101  
 //              Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)  
 //              David Dillard, VERITAS Software Corp.  
 //                  (david.dillard@veritas.com)  
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #include "Thread.h" #include "Thread.h"
   #include <errno.h>
 #include <exception> #include <exception>
 #include <Pegasus/Common/Tracer.h> #include <Pegasus/Common/Tracer.h>
   #include <Pegasus/Common/AutoPtr.h>
 #include "Time.h" #include "Time.h"
  
 PEGASUS_USING_STD; PEGASUS_USING_STD;
Line 66 
Line 56 
  
 extern "C" void *_start_wrapper(void *arg_) extern "C" void *_start_wrapper(void *arg_)
 { {
     StartWrapperArg *arg = (StartWrapperArg *) arg_;      // Clean up dynamic memory now to prevent a leak if the thread is canceled.
       StartWrapperArg arg;
       arg.start = ((StartWrapperArg *) arg_)->start;
       arg.arg = ((StartWrapperArg *) arg_)->arg;
       delete (StartWrapperArg *) arg_;
  
     void *return_value = (*arg->start) (arg->arg);      // establish cancelability of the thread
     delete arg;      pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
       pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
   
       void *return_value = (*arg.start) (arg.arg);
  
     return return_value;     return return_value;
 } }
  
 void Thread::cancel() void Thread::cancel()
 { {
     _cancelled = true;      pthread_cancel(_handle.thid.thread);
     pthread_cancel(_handle.thid.tt_handle());  
 }  
   
 void Thread::test_cancel()  
 {  
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)  
     pthread_testintr();  
 #else  
     pthread_testcancel();  
 #endif  
 }  
   
 Boolean Thread::is_cancelled(void)  
 {  
     return _cancelled;  
 } }
  
 void Thread::thread_switch() void Thread::thread_switch()
 { {
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)  #if defined(PEGASUS_OS_ZOS)
     pthread_yield(NULL);     pthread_yield(NULL);
 #else #else
     sched_yield();     sched_yield();
 #endif #endif
 } }
  
 /*  
 ATTN: why are these missing on other platforms?  
 */  
 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)  
 void Thread::suspend()  
 {  
     pthread_kill(_handle.thid.tt_handle(), SIGSTOP);  
 }  
   
 void Thread::resume()  
 {  
     pthread_kill(_handle.thid.tt_handle(), SIGCONT);  
 }  
 #endif  
   
 void Thread::sleep(Uint32 msec) void Thread::sleep(Uint32 msec)
 { {
     Threads::sleep(msec);     Threads::sleep(msec);
 } }
  
 void Thread::join(void)  void Thread::join()
 { {
     if (!_is_detached && Threads::id(_handle.thid) != 0)      if (!_is_detached && !Threads::null(_handle.thid))
         pthread_join(_handle.thid.tt_handle(), &_exit_code);          pthread_join(_handle.thid.thread, &_exit_code);
  
     Threads::clear(_handle.thid);     Threads::clear(_handle.thid);
 } }
  
 void Thread::thread_init(void)  void Thread::detach()
 {  
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)  
     pthread_setintr(PTHREAD_INTR_ENABLE);  
     pthread_setintrtype(PTHREAD_INTR_ASYNCHRONOUS);  
 #else  
     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);  
     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);  
 #endif  
     _cancel_enabled = true;  
 }  
   
 void Thread::detach(void)  
 { {
     _is_detached = true;     _is_detached = true;
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)  #if defined(PEGASUS_OS_ZOS)
     pthread_t  thread_id=_handle.thid.tt_handle();      pthread_t  thread_id=_handle.thid.thread;
     pthread_detach(&thread_id);     pthread_detach(&thread_id);
 #else #else
     pthread_detach(_handle.thid.tt_handle());      pthread_detach(_handle.thid.thread);
 #endif #endif
 } }
  
Line 169 
Line 124 
     // are no insufficient memory.  Hence we are checking for both.  See bug     // are no insufficient memory.  Hence we are checking for both.  See bug
     // 386.     // 386.
  
       if (rc == -1)
           rc = errno;
     if ((rc == EAGAIN) || (rc == ENOMEM))     if ((rc == EAGAIN) || (rc == ENOMEM))
     {     {
         Threads::clear(_handle.thid);         Threads::clear(_handle.thid);
Line 184 
Line 141 
     return PEGASUS_THREAD_OK;     return PEGASUS_THREAD_OK;
 } }
  
 static sigset_t *block_signal_mask(sigset_t * sig)  Thread::Thread(
 {      ThreadReturnType(PEGASUS_THREAD_CDECL* start) (void*),
     sigemptyset(sig);      void* parameter,
     // should not be used for main()      Boolean detached)
     sigaddset(sig, SIGHUP);      : _is_detached(detached),
     sigaddset(sig, SIGINT);        _start(start),
     // maybe useless, since KILL can't be blocked according to POSIX        _cleanup(),
     sigaddset(sig, SIGKILL);        _thread_parm(parameter),
         _exit_code(0)
     sigaddset(sig, SIGABRT);  
     sigaddset(sig, SIGALRM);  
     sigaddset(sig, SIGPIPE);  
   
   
 // Note: older versions of the linux pthreads library use SIGUSR1 and SIGUSR2  
 // internally to stop and start threads that are blocking, the newer ones  
 // implement this through the kernel's real time signals  
 // since SIGSTOP/CONT can handle suspend()/resume() on Linux  
 // block them  
 // #if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU)  
 //     sigaddset(sig, SIGUSR1);  
 //     sigaddset(sig, SIGUSR2);  
 // #endif  
 #ifndef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM  
     pthread_sigmask(SIG_BLOCK, sig, NULL);  
 #else  
     sigprocmask(SIG_BLOCK, sig, NULL);  
 #endif  
     return sig;  
 }  
   
 Thread::Thread(ThreadReturnType(PEGASUS_THREAD_CDECL * start) (void *), void *parameter, Boolean detached):_is_detached(detached),  
 _cancel_enabled(true),  
 _cancelled(false),  
 _start(start), _cleanup(), _tsd(), _thread_parm(parameter), _exit_code(0)  
 { {
     Threads::clear(_handle.thid);     Threads::clear(_handle.thid);
       memset(_tsd, 0, sizeof(_tsd));
 } }
  
 Thread::~Thread() Thread::~Thread()
Line 246 
Line 178 
  
 #if defined(PEGASUS_HAVE_WINDOWS_THREADS) #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
  
 ThreadStatus Thread::run(void)  ThreadStatus Thread::run()
 { {
     // Note: A Win32 thread ID is not the same thing as a pthread ID.     // Note: A Win32 thread ID is not the same thing as a pthread ID.
     // Win32 threads have both a thread ID and a handle.  The handle     // Win32 threads have both a thread ID and a handle.  The handle
Line 259 
Line 191 
     tt.handle = (HANDLE) _beginthreadex(NULL, 0, _start, this, 0, &threadid);     tt.handle = (HANDLE) _beginthreadex(NULL, 0, _start, this, 0, &threadid);
     _handle.thid = tt;     _handle.thid = tt;
  
     if (Threads::id(_handle.thid) == 0)      if (Threads::null(_handle.thid))
     {     {
         if (errno == EAGAIN)         if (errno == EAGAIN)
         {         {
Line 273 
Line 205 
     return PEGASUS_THREAD_OK;     return PEGASUS_THREAD_OK;
 } }
  
 void Thread::cancel(void)  void Thread::cancel()
 { {
     _cancelled = true;     _cancelled = true;
 } }
  
 void Thread::test_cancel(void)  void Thread::thread_switch()
 {  
     if (_cancel_enabled && _cancelled)  
     {  
         exit_self(0);  
     }  
 }  
   
 Boolean Thread::is_cancelled(void)  
 {  
     return _cancelled;  
 }  
   
 void Thread::thread_switch(void)  
 { {
     Sleep(0);     Sleep(0);
 } }
Line 301 
Line 220 
     Sleep(milliseconds);     Sleep(milliseconds);
 } }
  
 void Thread::join(void)  void Thread::join()
 { {
     if (Threads::id(_handle.thid) != 0)      if (!Threads::null(_handle.thid))
     {     {
         if (!_is_detached)         if (!_is_detached)
         {         {
Line 335 
Line 254 
     }     }
 } }
  
 void Thread::thread_init(void)  void Thread::detach()
 {  
     _cancel_enabled = true;  
 }  
   
 void Thread::detach(void)  
 { {
     _is_detached = true;     _is_detached = true;
 } }
  
 Thread::Thread(ThreadReturnType(PEGASUS_THREAD_CDECL * start) (void *),  Thread::Thread(
       ThreadReturnType(PEGASUS_THREAD_CDECL* start)(void*),
                void *parameter,                void *parameter,
                Boolean detached):_is_detached(detached),                Boolean detached):_is_detached(detached),
 _cancel_enabled(true),  
 _cancelled(false), _cancelled(false),
 _start(start), _cleanup(), _tsd(), _thread_parm(parameter), _exit_code(0)      _start(start),
       _cleanup(),
       _thread_parm(parameter),
       _exit_code(0)
 { {
     Threads::clear(_handle.thid);     Threads::clear(_handle.thid);
       memset(_tsd, 0, sizeof(_tsd));
 } }
  
 Thread::~Thread() Thread::~Thread()
Line 375 
Line 293 
 // //
 //============================================================================== //==============================================================================
  
 void thread_data::default_delete(void *data)  
 {  
     if (data != NULL)  
         ::operator  delete(data);  
 }  
   
 void language_delete(void *data) void language_delete(void *data)
 { {
     if (data != NULL)     if (data != NULL)
Line 414 
Line 326 
     {     {
         cu.reset(_cleanup.remove_front());         cu.reset(_cleanup.remove_front());
     }     }
     catch(IPCException &)      catch (...)
     {     {
         PEGASUS_ASSERT(0);         PEGASUS_ASSERT(0);
     }     }
     if (execute == true)     if (execute == true)
       {
         cu->execute();         cu->execute();
 } }
   }
   
 //thread_data *Thread::put_tsd(const Sint8 *key, void (*delete_func)(void *), Uint32 size, void *value)  
  
  
 void Thread::exit_self(ThreadReturnType exit_code) void Thread::exit_self(ThreadReturnType exit_code)
 { {
 #if defined(PEGASUS_PLATFORM_HPUX_ACC) || \  #if !defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) \
     defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)      && !defined(PEGASUS_PLATFORM_PASE_ISERIES_IBMCXX)
     // NOTE: pthread_exit exhibits unusual behavior on RHEL 3 U2, as      Threads::exit(exit_code);
     // documented in Bugzilla 3836.  Where feasible, it may be advantageous  
     // to avoid using this function.  
     pthread_exit(exit_code);  
 #else #else
     // execute the cleanup stack and then return     // execute the cleanup stack and then return
     while (_cleanup.size())     while (_cleanup.size())
Line 442 
Line 350 
         {         {
             cleanup_pop(true);             cleanup_pop(true);
         }         }
         catch(IPCException &)          catch (...)
         {         {
             PEGASUS_ASSERT(0);             PEGASUS_ASSERT(0);
             break;             break;
Line 461 
Line 369 
     {     {
         if (Thread::_key_error)         if (Thread::_key_error)
         {         {
             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,              PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL1,
                           "Thread: ERROR - thread key error");                           "Thread: ERROR - thread key error");
             return -1;             return -1;
         }         }
  
         if (TSDKey::create(&Thread::_platform_thread_key) == 0)         if (TSDKey::create(&Thread::_platform_thread_key) == 0)
         {         {
             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,              PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL4,
                           "Thread: able to create a thread key");                           "Thread: able to create a thread key");
             Thread::_key_initialized = true;             Thread::_key_initialized = true;
         }         }
         else         else
         {         {
             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,              PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL1,
                           "Thread: ERROR - unable to create a thread key");                           "Thread: ERROR - unable to create a thread key");
             Thread::_key_error = true;             Thread::_key_error = true;
             return -1;             return -1;
Line 505 
Line 413 
             set_thread_specific(Thread::_platform_thread_key,             set_thread_specific(Thread::_platform_thread_key,
                                 (void *) thrd) == 0)                                 (void *) thrd) == 0)
         {         {
             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,              PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL4,
                 "Successful set Thread * into thread specific storage");                 "Successful set Thread * into thread specific storage");
         }         }
         else         else
         {         {
             Tracer::trace(TRC_THREAD, Tracer::LEVEL4,              PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL1,
                 "ERROR: error setting Thread * into thread specific storage");                 "ERROR: error setting Thread * into thread specific storage");
         }         }
     }     }
Line 525 
Line 433 
     if (curThrd == NULL)     if (curThrd == NULL)
         return NULL;         return NULL;
     AcceptLanguageList *acceptLangs =     AcceptLanguageList *acceptLangs =
         (AcceptLanguageList *) curThrd->reference_tsd("acceptLanguages");          (AcceptLanguageList *) curThrd->reference_tsd(TSD_ACCEPT_LANGUAGES);
     curThrd->dereference_tsd();     curThrd->dereference_tsd();
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     return acceptLangs;     return acceptLangs;
 } }
  
 void Thread::setLanguages(AcceptLanguageList * langs)   // l10n  void Thread::setLanguages(const AcceptLanguageList& langs)
 { {
     PEG_METHOD_ENTER(TRC_THREAD, "Thread::setLanguages");     PEG_METHOD_ENTER(TRC_THREAD, "Thread::setLanguages");
  
     Thread *currentThrd = Thread::getCurrent();     Thread *currentThrd = Thread::getCurrent();
     if (currentThrd != NULL)     if (currentThrd != NULL)
     {     {
           AutoPtr<AcceptLanguageList> langsCopy(new AcceptLanguageList(langs));
   
         // 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(
               TSD_ACCEPT_LANGUAGES,
                              language_delete,                              language_delete,
                              sizeof (AcceptLanguageList *), langs);              sizeof (AcceptLanguageList *),
               langsCopy.get());
   
           langsCopy.release();
     }     }
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
  
 void Thread::clearLanguages()   // l10n  void Thread::clearLanguages()
 { {
     PEG_METHOD_ENTER(TRC_THREAD, "Thread::clearLanguages");     PEG_METHOD_ENTER(TRC_THREAD, "Thread::clearLanguages");
  
Line 555 
Line 469 
     if (currentThrd != NULL)     if (currentThrd != NULL)
     {     {
         // deletes the old tsd         // deletes the old tsd
         currentThrd->delete_tsd("acceptLanguages");          currentThrd->delete_tsd(TSD_ACCEPT_LANGUAGES);
     }     }
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();


Legend:
Removed from v.1.91  
changed lines
  Added in v.1.113

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2