TPosixThread.cxx

Go to the documentation of this file.
00001 // @(#)root/thread:$Id: TPosixThread.cxx 35586 2010-09-22 14:06:57Z rdm $
00002 // Author: Fons Rademakers   02/07/97
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TPosixThread                                                         //
00015 //                                                                      //
00016 // This class provides an interface to the posix thread routines.       //
00017 //                                                                      //
00018 //////////////////////////////////////////////////////////////////////////
00019 
00020 #include "TPosixThread.h"
00021 
00022 
00023 ClassImp(TPosixThread)
00024 
00025 
00026 //______________________________________________________________________________
00027 Int_t TPosixThread::Run(TThread *th)
00028 {
00029    // Create a pthread.
00030 
00031    int det;
00032    pthread_t id;
00033    pthread_attr_t *attr = new pthread_attr_t;
00034 
00035    pthread_attr_init(attr);
00036 
00037    // Set detach state
00038    det = (th->fDetached) ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE;
00039 
00040    pthread_attr_setdetachstate(attr, det);
00041    int ierr = pthread_create(&id, attr, &TThread::Function, th);
00042    if (!ierr) th->fId = (Long_t) id;
00043 
00044    pthread_attr_destroy(attr);
00045    delete attr;
00046 
00047    return ierr;
00048 }
00049 
00050 //______________________________________________________________________________
00051 Int_t TPosixThread::Join(TThread *th, void **ret)
00052 {
00053    // Join  suspends  the  execution  of the calling thread until the
00054    // thread identified by th terminates, either by  calling  pthread_exit
00055    // or by being cancelled.
00056 
00057    return pthread_join((pthread_t) th->fId, ret);
00058 }
00059 
00060 //______________________________________________________________________________
00061 Int_t TPosixThread::Exit(void *ret)
00062 {
00063    // Terminates the execution of the calling thread.
00064 
00065    pthread_exit(ret);
00066    return 0;
00067 }
00068 
00069 //______________________________________________________________________________
00070 Int_t TPosixThread::Kill(TThread *th)
00071 {
00072    // Cancellation is the mechanism by which a thread can terminate the
00073    // execution of another thread.
00074 
00075    return pthread_cancel((pthread_t) th->fId);
00076 }
00077 
00078 //______________________________________________________________________________
00079 Int_t TPosixThread::SetCancelOff()
00080 {
00081    // Turn off the cancellation state of the calling thread.
00082 
00083    return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
00084 }
00085 
00086 //______________________________________________________________________________
00087 Int_t TPosixThread::SetCancelOn()
00088 {
00089    // Turn on the cancellation state of the calling thread.
00090 
00091    return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
00092 }
00093 
00094 //______________________________________________________________________________
00095 Int_t TPosixThread::SetCancelAsynchronous()
00096 {
00097    // Set the cancellation response type of the calling thread to
00098    // asynchronous, i.e. cancel as soon as the cancellation request
00099    // is received.
00100 
00101    return pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
00102 }
00103 
00104 //______________________________________________________________________________
00105 Int_t TPosixThread::SetCancelDeferred()
00106 {
00107    // Set the cancellation response type of the calling thread to
00108    // deferred, i.e. cancel only at next cancellation point.
00109 
00110    return pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, 0);
00111 }
00112 
00113 //______________________________________________________________________________
00114 Int_t TPosixThread::CancelPoint()
00115 {
00116    // Introduce an explicit cancellation point.
00117 
00118    int istate;
00119    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &istate);
00120    pthread_testcancel();
00121    pthread_setcancelstate(istate, 0);
00122 
00123    return 0;
00124 }
00125 
00126 //______________________________________________________________________________
00127 Int_t TPosixThread::CleanUpPush(void **main, void *free, void *arg)
00128 {
00129    // Add thread cleanup function.
00130 
00131    // pthread_cleanup_push(free, arg);
00132    if (!free) Error("CleanUpPush", "cleanup rountine = 0");
00133    new TPosixThreadCleanUp(main, free, arg);
00134    return 0;
00135 }
00136 
00137 //______________________________________________________________________________
00138 Int_t TPosixThread::CleanUpPop(void **main,Int_t exe)
00139 {
00140    // Pop thread cleanup function from stack.
00141 
00142    //  pthread_cleanup_pop(exe); // happy pthread future
00143 
00144    if (!main || !*main) return 1;
00145    TPosixThreadCleanUp *l = (TPosixThreadCleanUp*)(*main);
00146    if (!l->fRoutine) Error("CleanUpPop", "cleanup routine = 0");
00147    if (exe && l->fRoutine) ((void (*)(void*))(l->fRoutine))(l->fArgument);
00148    *main = l->fNext;  delete l;
00149    return 0;
00150 }
00151 
00152 //______________________________________________________________________________
00153 Int_t TPosixThread::CleanUp(void **main)
00154 {
00155    // Default thread cleanup routine.
00156 
00157    if (gDebug > 0)
00158       Info("Cleanup", "cleanup 0x%lx", (Long_t)*main);
00159    while (!CleanUpPop(main, 1)) { }
00160    return 0;
00161 }
00162 
00163 //______________________________________________________________________________
00164 Long_t TPosixThread::SelfId()
00165 {
00166    // Return the thread identifier for the calling thread.
00167 
00168    return (Long_t) pthread_self();
00169 }
00170 
00171 //   Clean Up section. PTHREAD implementations of cleanup after cancel are
00172 //   too different and often too bad. Temporary I invent my own bicycle.
00173 //                                                              V.Perev.
00174 
00175 //______________________________________________________________________________
00176 TPosixThreadCleanUp::TPosixThreadCleanUp(void **main, void *routine, void *arg)
00177 {
00178    //cleanup function
00179    fNext = (TPosixThreadCleanUp*)*main;
00180    fRoutine = routine; fArgument = arg;
00181    *main  = this;
00182 }

Generated on Tue Jul 5 14:12:02 2011 for ROOT_528-00b_version by  doxygen 1.5.1