// @(#)root/thread:$Name:  $:$Id: TPosixThread.cxx,v 1.11 2005/01/05 01:25:19 rdm Exp $
// Author: Fons Rademakers   02/07/97

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TPosixThread                                                         //
//                                                                      //
// This class provides an interface to the posix thread routines.       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TPosixThread.h"


ClassImp(TPosixThread)


//______________________________________________________________________________
 Int_t TPosixThread::Run(TThread *th)
{
   // Create a pthread.

   int det;
   pthread_t id;
   pthread_attr_t *attr = new pthread_attr_t;

   pthread_attr_init(attr);

   // Set detach state
   det = (th->fDetached) ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE;

   pthread_attr_setdetachstate(attr, det);
   int ierr = pthread_create(&id, attr, &TThread::Function, th);
   if (!ierr) th->fId = (Long_t) id;
   if (attr) {
      pthread_attr_destroy(attr);
      delete attr;
   }
   return ierr;
}

//______________________________________________________________________________
 Int_t TPosixThread::Join(TThread *th, void **ret)
{
   // Join  suspends  the  execution  of the calling thread until the
   // thread identified by th terminates, either by  calling  pthread_exit
   // or by being cancelled.

   return pthread_join((pthread_t) th->fId, ret);
}

//______________________________________________________________________________
 Int_t TPosixThread::Exit(void *ret)
{
   // Terminates the execution of the calling thread.

   pthread_exit(ret);
   return 0;
}

//______________________________________________________________________________
 Int_t TPosixThread::Kill(TThread *th)
{
   // Cancellation is the mechanism by which a thread can terminate the
   // execution of another thread.

   return pthread_cancel((pthread_t) th->fId);
}

//______________________________________________________________________________
 Int_t TPosixThread::SetCancelOff()
{
   // Turn off the cancellation state of the calling thread.

   return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
}

//______________________________________________________________________________
 Int_t TPosixThread::SetCancelOn()
{
   // Turn on the cancellation state of the calling thread.

   return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
}

//______________________________________________________________________________
 Int_t TPosixThread::SetCancelAsynchronous()
{
   // Set the cancellation response type of the calling thread to
   // asynchronous, i.e. cancel as soon as the cancellation request
   // is received.

   return pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
}

//______________________________________________________________________________
 Int_t TPosixThread::SetCancelDeferred()
{
   // Set the cancellation response type of the calling thread to
   // deferred, i.e. cancel only at next cancellation point.

   return pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, 0);
}

//______________________________________________________________________________
 Int_t TPosixThread::CancelPoint()
{
   // Introduce an explicit cancellation point.

   int istate;
   pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &istate);
   pthread_testcancel();
   pthread_setcancelstate(istate, 0);

   return 0;
}

//______________________________________________________________________________
 Int_t TPosixThread::CleanUpPush(void **main, void *free, void *arg)
{
   // Add thread cleanup function.

   // pthread_cleanup_push(free, arg);
   if (!free) Error("CleanUpPush", "cleanup rountine = 0");
   new TPosixThreadCleanUp(main, free, arg);
   return 0;
}

//______________________________________________________________________________
 Int_t TPosixThread::CleanUpPop(void **main,Int_t exe)
{
   // Pop thread cleanup function from stack.

   //  pthread_cleanup_pop(exe); // happy pthread future

   if (!main || !*main) return 1;
   TPosixThreadCleanUp *l = (TPosixThreadCleanUp*)(*main);
   if (!l->fRoutine) Error("CleanUpPop", "cleanup routine = 0");
   if (exe && l->fRoutine) ((void (*)(void*))(l->fRoutine))(l->fArgument);
   *main = l->fNext;  delete l;
   return 0;
}

//______________________________________________________________________________
 Int_t TPosixThread::CleanUp(void **main)
{
   // Default thread cleanup routine.

   if (gDebug > 0)
      Info("Cleanup", "cleanup 0x%lx", (Long_t)*main);
   while (!CleanUpPop(main, 1)) { }
   return 0;
}

//______________________________________________________________________________
 Long_t TPosixThread::SelfId()
{
   // Return the thread identifier for the calling thread.

   return (Long_t) pthread_self();
}

//   Clean Up section. PTHREAD implementations of cleanup after cancel are
//   too different and often too bad. Temporary I invent my own bicycle.
//                                                              V.Perev.

//______________________________________________________________________________
TPosixThreadCleanUp::TPosixThreadCleanUp(void **main, void *routine, void *arg)
{
   fNext = (TPosixThreadCleanUp*)*main;
   fRoutine = routine; fArgument = arg;
   *main  = this;
}


ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.