Provided by: liblcgdm-dev_1.13.0-1_amd64 bug


       Cthread - LCG Thread inferface


       #include <Cthread_api.h>

       int Cthread_create(void *(*startroutine)(void *), void * arg);

       int Cthread_create_detached(void *(*startroutine)(void *),void *arg);

       int Cthread_join(int cid, int **status);

       int Cthread_mutex_lock(void *addr);

       int Cthread_mutex_trylock(void *addr);

       int Cthread_mutex_timedlock(void *addr, int timeout);

       int Cthread_mutex_unlock(void *addr);

       int Cthread_mutex_destroy(void *addr);

       int Cthread_cond_wait(void *addr);

       int Cthread_cond_timedwait(void *addr, int timeout);

       int Cthread_cond_signal(void *addr);

       int Cthread_cond_broadcast(void *addr);

       int Cthread_detach(int cid);

       int Cthread_kill(int cid, int signo);

       int Cthread_exit(void *status);

       int Cthread_self(void);

       int Cthread_getspecific(int *global_key, void **addr);

       int Cthread_setspecific(int *global_key, void * addr);


       Cthread  is  a  common  API  interface  for multithreaded programs, although there is also
       support for nonthreaded application, where some of  the  Cthread  functions  then  becomes

       For non-thread applications see the section NON-THREAD ENVIRONMENT

       Any created thread is identified uniquely with a cid, standing for Cthread identifier.

       In  multithread  environment, Cthread is an interface to pthread functions on UNIX, and an
       interface to Win32 C-runtime library on Windows/NT.

       Cthread_create is creating  a  thread  given  its  starting  point  startroutine  and  its
       arguments  arg  address.  The  thread is created with the default parameters, e.g. it is a
       joinable thread.

       Return value is the Cthread identifier cid , greater or equal to zero, or -1 on error.

       Cthread_create_detached takes the same arguments as Cthread_create and (tries) to create a
       detachable  thread,  which  will  then make it act as a daemon. This means that ressources
       used by this thread will be freed immediately when it terminates. On the other hand,  such
       thread cannot be synchronized with other threads using the Cthread_join method.

       You  have  to  remind  that  creating  a  detachable thread do not work immediately at the
       creation step on every thread implementation, in particular in the  DCE  threads.  If  the
       implementation  do  not  allow  this  at creation time, then Cthread_create_detached calls
       Cthread_create. Please have a look at Cthread_detach section.

       Return value is the Cthread identifier cid , greater or equal to zero, or -1 on error.

       Cthread_exit makes current thread exiting. If status isn't NULL, it is assumed to point to
       an  integer  whose  value  if  the  status that a Cthread_join would received, in case the
       thread is joinable. Please note that Cthread_exit  is  dangerous  and  non-recommended  on
       Windows platform.

       Return value is 0 on success, or -1 on error.

       Cthread_kill  sends  signo signal number to the thread cid.  This affect the status that a
       Cthread_join would received, in case the thread to be killed is joinable. Please note that
       Cthread_kill is not supported on DCE threads.

       Return value is 0 on success, or -1 on error.

       Cthread_join  suspends  the  calling  thread  until  the  one  identified with the Cthread
       identifier cid terminates. If the  status  parameter  is  not  NULL,  the  status  of  the
       terminating  thread cid is stored there. This status is the pointer returned by thread cid
       at its end.

       Return value is 0 on success, or -1 on error.

       Cthread_mutex_lock is an alias for Cthread_mutex_timedlock with a timeout of -1.

       Cthread_mutex_trylock is an alias for Cthread_mutex_timedlock with a timeout of 0.

       Cthread_mutex_timedlock is acquiring a mutex,  creating  it  if  necessary,  on  the  addr
       address.  The  second parameter is the eventual timeout in seconds. If this parameter is <
       0, the calling thread is suspended until it is granted access to addr , if it is zero, the
       calling  thread  will  try  to  gain  the lock, and if it is greater than zero the calling
       thread will wait up to timeout seconds.

       Please note that, in Cthread, a creation of a mutex is always associated with  a  creation
       of a conditionnal variable. See Cthread_cond_timedwait and Cthread_cond_broadcast_.

       Return value is 0 on success, or -1 on error.

       Cthread_mutex_unlock  is  unlocking  the  mutex that the calling thread is assumed to have
       acquired previously, calling Cthread_mutex_timedlock on the addr address.

       Cthread_cond_wait is an alias for Cthread_cond_timedwait with a timeout of -1.

       Cthread_cond_timedwait is waiting for a  condition  variable,  which  is,  by  default  in
       Cthread,  broadcasted,  associated  with  a  mutex previously created on the addr address.
       Calling  this  function  before  the  creation   and   the   lock   of   a   mutex,   with
       Cthread_mutex_timedlock is a programming error.

       While the thread is waiting on a condition to arise on the addr address, the corresponding
       lock is released. It will be acquired as soon as the condition happens. Please  note  that
       the  use of condition is subject to normal thread programming rules, e.g. the lock, a loop
       on a predicate, a wait inside the loop, and the unlock.

       If the timeout parameter, in seconds, is greater than zero, then  the  function  will  not
       suspend the calling thread more than this limit.

       Return value is 0 on success, or -1 on error.

       Cthread_cond_signal is an alias for Cthread_cond_broadcast.

       Cthread_cond_broadcast restarts threads that are waiting on a condition variable vs.  addr

       Return value is 0 on success, or -1 on error.

       Cthread_detach is detaching the calling thread, identified with  cid  Cthread  identifier.
       Whereas  the  normal  thread  packages  that allow a thread to be detached at the creation
       step, see Cthread_create_detached, returns an error if such a  detached  thread  tries  to
       detach  himself  again,  Cthread_detach  will not, because of this different behaviour vs.
       different thread implementations: it is not  possible  everywhere  to  create  a  detached
       thread immediately, like in DCE threads.

       This   means   that   if   a   user   is   creating   a   thread  with  Cthread_create  or
       Cthread_create_detached, the created  thread  will,  in  any  case,  be  allowed  to  call
       Cthread_detach:  if  the  calling thread is not yet detached, it will be changed so forth,
       and if the calling thread is already detached, the return value will be 0.

       Return value is 0 on success, or -1 on error.

       Cthread_mutex_destroy is removing its corresponding entry in Cthread internal linked list,
       freeing  all thread associated stuff, like the mutex itself, and the conditionnal variable
       (see Cthread_mutex_timedlock).

       Return value is 0 on success, or -1 on error.

       Cthread_self is returning the Cthread identifier cid of the calling thread.

       Return value is the cid (greater or equal to zero) on success, or -1 on error.

       Cthread_getspecific is creating and/or getting a thread-specific storage address for every
       instance of the global_key address, storing its result in addr location. The first time it
       is called, the stored result is NULL, next time it will be the address of the  memory  the
       user   would   have   previously   allocated   and   associated   with   the   key   using

       Return value is 0 on success, or -1 on error.

       Cthread_setspecific is associating a memory, starting at  addr  that  he  have  previously
       allocated,  with  the  global_key address. If he tries to do so without calling previously
       Cthread_getspecific, then such a call will be done internally.

       Return value is 0 on success, or -1 on error.


       Beyond the errno value, Cthread is setting the serrno value to generic values that can be:

              LCG Thread interface initialization error

              A thread initialisation call failed. In principle, on UNIX this will be a  call  to
              pthread_mutex_init (and possibly pthread_mutexattr_init) that failed, on Windows/NT
              this might be a call to CreateMutex.

              LCG Thread interface failure in calling your thread library

              A thread call to your native system library (like the pthread one on UNIX)  failed.
              Please  note  that  this  is  differentiated  to the Cthread initialization and can
              happen if you are using too much thread keys, for example. This is  really  a  run-
              time error only concerning your operating system thread interface. Any other system
              call failure, but not a thread one, and not at the initialisation  step,  will  set
              serrno to SEINTERNAL

              Operation not supported

              This can be generated only if you compiled Cthread with a -DCTHREAD_PROTO flag that
              Cthread do not know about. Check your LCG configuration site.def.

              Internal error

              You can have more information by  compiling  the  Cthread  package  with  the  flag
              -DCTHREAD_DEBUG,  and  catching  the  printout  on  your stderr stream. This is any
              system call that failed (like malloc()), except those to the  thread  library  (for
              which SECTHREADERR or SECTHREADINIT is to  be found), or any critical internal run-
              time error (such as a non correct value found in some Cthread internal structures).

       SETIMEDOUT (routines with a timeout parameter only)
              Timed out

              You called a routine with a timeout  value  greater  than  zero  that  reached  the
              maximum number of timeout seconds in waiting state.

              Invalid parameters

              You called a routine with invalid parameter(s). Please check your code.


       Here is an example with thread-specific data

       #include <Cthread_api.h> /* Cthread include file */
       #include <stdio.h>       /* For I/O functions and definitions */
       #define NTHREADS 5 /* Number of threads */
       #define NLOOP    5 /* Number of loops in threads */

       static int global_key;

       /* Internal Prototypes */
       void *mythread(void *);
       void  testit();

       int main() {
         int i, n;

         for (i=1; i <= NTHREADS; i++) {
           if ((n = Cthread_create(&mythread,NULL)) < 0) {
           } else {
             fprintf(stderr,"[main] --> Created Cthread ID %d\n",n);


       void *mythread(void *arg) {
         int i;

         /* Call the same routine NLOOP times */
         for (i=1; i <= NLOOP; i++) {


       void testit() {
         char *addr = NULL;
         int   n;

         if ((n = Cthread_detach(Cthread_self())))

         if ((n = Cthread_getspecific(&global_key,(void **) &addr)))

         if (addr == NULL) {
           addr = malloc(100);
           fprintf(stderr,"[%d] --> new 0x%x\n",
           if (Cthread_setspecific(&global_key,addr))
         } else {
           fprintf(stderr,"[%d] --> old 0x%x\n",

         sprintf(addr,"[%d] Print with TSD buffer : Cthread ID=%d\n",




       In such an environment, almost all methods becomes no-op, except:

              Creation of process(es):
                     Cthread_create_detached (equivalent to Cthread_create)

              Use of "Process"-specific variables:

              For  these  two  last  functions,  Cthread will garbage itself its eventual list of
              "Process"-specific variables. This means that, as in a thread environment, the user
              will   not   have   to  free  memory  allocated  and  registered  with  a  call  to


       pthread, DCE, LinuxThreads, Win32


       LCG Grid Deployment Team