pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:1:   #include "global.h" - RCSID("$Id: threads.c,v 1.172 2001/11/01 18:40:12 mast Exp $"); + RCSID("$Id: threads.c,v 1.173 2001/11/02 14:05:14 mast Exp $");      PMOD_EXPORT int num_threads = 1;   PMOD_EXPORT int threads_disabled = 0;      #ifdef _REENTRANT   #include "threads.h"   #include "array.h"   #include "mapping.h"   #include "object.h"   #include "pike_macros.h"
pike.git/src/threads.c:17:   #include "program_id.h"   #include "gc.h"   #include "main.h"   #include "module_support.h"   #include "pike_types.h"   #include "operators.h"   #include "bignum.h"      #include <errno.h>    - PMOD_EXPORT int live_threads = 0; + PMOD_EXPORT int live_threads = 0, disallow_live_threads = 0;   PMOD_EXPORT COND_T live_threads_change;   PMOD_EXPORT COND_T threads_disabled_change;   PMOD_EXPORT size_t thread_stack_size=256 * 1204;      /* SCO magic... */   int __thread_sys_behavior = 1;      #if !defined(HAVE_PTHREAD_ATFORK) && !defined(th_atfork)   #include "callback.h"   
pike.git/src/threads.c:201:   #endif /* HAVE_BROKEN_LINUX_THREAD_EUID */   };      struct thread_local   {    INT32 id;   };      static volatile IMUTEX_T *interleave_list = NULL;    + /* This is a variant of init_threads_disable that blocks all other +  * threads that might run pike code, but still doesn't block the +  * THREADS_ALLOW_UID threads. */   void low_init_threads_disable(void)   {    /* Serious black magic to avoid dead-locks */       if (!threads_disabled) {    THREADS_FPRINTF(0,    (stderr, "low_init_threads_disable(): Locking IM's...\n"));       if (Pike_interpreter.thread_id) {    /* Threads have been enabled. */
pike.git/src/threads.c:263:    threads_disabled++;    }       THREADS_FPRINTF(0,    (stderr, "low_init_threads_disable(): threads_disabled:%d\n",    threads_disabled));   }      /*! @decl object(_disable_threads) _disable_threads()    *! -  *! This function first posts a notice to all threads that it is time to stop. -  *! It then waits until all threads actually *have* stopped, and then then -  *! returns an object. All other threads will be blocked from running until -  *! that object has been freed/destroyed. +  *! This function first posts a notice to all threads that it is time +  *! to stop. It then waits until all threads actually *have* stopped, +  *! and then then returns a lock object. All other threads will be +  *! blocked from running until that object has been freed/destroyed.    *! -  +  *! It's mainly useful to do things that require a temporary uid/gid +  *! change, since on many OS the effective user and group applies to +  *! all threads. +  *!    *! @note -  *! This function can completely block Pike if used incorrectly. -  *! Use with extreme caution. +  *! You should make sure that the returned object is freed even if +  *! some kind of error is thrown. That means in practice that it +  *! should only have references (direct or indirect) from function +  *! local variables. Also, it shouldn't be referenced from cyclic +  *! memory structures, since those are only destructed by the periodic +  *! gc. (This advice applies to mutex locks in general, for that +  *! matter.)    */   void init_threads_disable(struct object *o)   { -  low_init_threads_disable(); +  disallow_live_threads = 1;       if(live_threads) {    SWAP_OUT_CURRENT_THREAD();    while (live_threads) {    THREADS_FPRINTF(0,    (stderr,    "_disable_threads(): Waiting for %d threads to finish\n",    live_threads));    low_co_wait_interpreter(&live_threads_change);    }    SWAP_IN_CURRENT_THREAD();    } -  +  +  low_init_threads_disable();   }      void exit_threads_disable(struct object *o)   {    THREADS_FPRINTF(0, (stderr, "exit_threads_disable(): threads_disabled:%d\n",    threads_disabled));    if(threads_disabled) {    if(!--threads_disabled) {    IMUTEX_T *im = (IMUTEX_T *)interleave_list;   
pike.git/src/threads.c:309:    THREADS_FPRINTF(0,    (stderr,    "exit_threads_disable(): Unlocking IM 0x%p\n", im));    mt_unlock(&(im->lock));    im = im->next;    }       mt_unlock(&interleave_lock);       THREADS_FPRINTF(0, (stderr, "_exit_threads_disable(): Wake up!\n")); +  disallow_live_threads = 0;    co_broadcast(&threads_disabled_change);   #ifdef PIKE_DEBUG    threads_disabled_thread = 0;   #endif    }   #ifdef PIKE_DEBUG    } else {    fatal("exit_threads_disable() called too many times!\n");   #endif /* PIKE_DEBUG */    }
pike.git/src/threads.c:582: Inside #if defined(DEBUG)
  #ifdef DEBUG    if(thread_for_id(th_self()) != Pike_interpreter.thread_id)    fatal("thread_for_id() (or Pike_interpreter.thread_id) failed!\n")       if(Pike_interpreter.backlink != OBJ2THREAD(Pike_interpreter.thread_id))    fatal("Hashlink is wrong!\n");   #endif       THREADS_ALLOW();    /* Allow other threads to run */ - #ifdef HAVE_THR_YIELD -  thr_yield(); - #endif +  th_yield();    THREADS_DISALLOW();      #ifdef DEBUG    if(thread_for_id(th_self()) != Pike_interpreter.thread_id)    fatal("thread_for_id() (or Pike_interpreter.thread_id) failed!\n")   #endif   }      TH_RETURN_TYPE new_thread_func(void * data)   {