pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:388:   static THREAD_T threads_disabled_thread = 0;   #endif   #ifdef INTERNAL_PROFILING   PMOD_EXPORT unsigned long thread_yields = 0;   #endif   static int th_running = 0;   static PIKE_MUTEX_T interpreter_lock;   static PIKE_MUTEX_T interpreter_lock_wanted;   PIKE_MUTEX_T thread_table_lock;   static PIKE_MUTEX_T interleave_lock; + static struct program *mutex_program = NULL;   static struct program *mutex_key = 0;   PMOD_EXPORT struct program *thread_id_prog = 0;   static struct program *thread_local_prog = 0;   PMOD_EXPORT ptrdiff_t thread_storage_offset;   static int live_threads = 0;   static COND_T live_threads_change;   static COND_T threads_disabled_change;      struct thread_local_var   {
pike.git/src/threads.c:2572:    *! support. The Condition class is not simulated otherwise, since that    *! can't be done accurately without continuations.    *!    *! @seealso    *! @[Mutex]    */      struct pike_cond {    COND_T cond;    int wait_count; +  struct object *mutex_obj;   };      #define THIS_COND ((struct pike_cond *)(CURRENT_STORAGE))    -  + /*! @decl void create(Thread.Mutex|void mutex) +  *! +  *! @param mutex +  *! Optional @[Mutex] that protects the resource that the +  *! condition signals for. +  */ + static void f_cond_create(INT32 args) + { +  struct pike_cond *cond = THIS_COND; +  struct object *mux = NULL; +  get_all_args("create", args, ".%O", &mux); +  if (cond->mutex_obj) { +  free_object(cond->mutex_obj); +  cond->mutex_obj = NULL; +  } +  if (mux) { +  struct program *prog = mux->prog; +  if (prog) { +  prog = prog->inherits[SUBTYPEOF(Pike_sp[-args])].prog; +  if (prog == mutex_program) { +  cond->mutex_obj = mux; +  add_ref(mux); +  } +  } +  } + } +    /*! @decl void wait(Thread.MutexKey mutex_key)    *! @decl void wait(Thread.MutexKey mutex_key, int(0..)|float seconds)    *! @decl void wait(Thread.MutexKey mutex_key, int(0..) seconds, @    *! int(0..999999999) nanos)    *!    *! Wait for condition.    *!    *! This function makes the current thread sleep until the condition    *! variable is signalled or the timeout is reached.    *!
pike.git/src/threads.c:2641:    if (args <= 2) {    FLOAT_TYPE fsecs = 0.0;    get_all_args(NULL, args, "%o.%F", &key, &fsecs);    seconds = (INT_TYPE) fsecs;    nanos = (INT_TYPE)((fsecs - seconds)*1000000000);    } else {    /* FIXME: Support bignum nanos. */    get_all_args(NULL, args, "%o%i%i", &key, &seconds, &nanos);    }    +  c = THIS_COND; +     if ((key->prog != mutex_key) ||    (!(OB2KEY(key)->initialized)) || -  (!(mut = OB2KEY(key)->mut))) { +  (!(mut = OB2KEY(key)->mut)) || +  (OB2KEY(key)->mutex_obj && (OB2KEY(key)->mutex_obj != c->mutex_obj))) {    Pike_error("Bad argument 1 to wait()\n");    }       if(args > 1) {    pop_n_elems(args - 1);    args = 1;    }    -  c = THIS_COND; -  +     /* Unlock mutex */    mutex_obj = OB2KEY(key)->mutex_obj;    mut->key=0;    OB2KEY(key)->mut=0;    OB2KEY(key)->mutex_obj = NULL;    co_signal(& mut->condition);       /* Wait and allow mutex operations */    SWAP_OUT_CURRENT_THREAD();    c->wait_count++;
pike.git/src/threads.c:2750:       THREADS_ALLOW();   #ifdef HAVE_NO_YIELD    sleep(0);   #else /* HAVE_NO_YIELD */    th_yield();   #endif /* HAVE_NO_YIELD */    THREADS_DISALLOW();    }    co_destroy(&(THIS_COND->cond)); +  +  if (THIS_COND->mutex_obj) { +  free_object(THIS_COND->mutex_obj); +  THIS_COND->mutex_obj = NULL;    } -  + }      /*! @endclass    */      /*! @class Thread    */      /*! @decl array(mixed) backtrace()    *!    *! Returns the current call stack for the thread.
pike.git/src/threads.c:3386:    tFunc(tOr(tInt02,tVoid),tObjIs_THREAD_MUTEX_KEY),0);    ADD_FUNCTION("trylock",f_mutex_trylock,    tFunc(tOr(tInt02,tVoid),tObjIs_THREAD_MUTEX_KEY),0);    ADD_FUNCTION("current_locking_thread",f_mutex_locking_thread,    tFunc(tNone,tObjIs_THREAD_ID), 0);    ADD_FUNCTION("current_locking_key",f_mutex_locking_key,    tFunc(tNone,tObjIs_THREAD_MUTEX_KEY), 0);    ADD_FUNCTION("_sprintf",f_mutex__sprintf,tFunc(tInt,tStr),0);    set_init_callback(init_mutex_obj);    set_exit_callback(exit_mutex_obj); +  mutex_program = Pike_compiler->new_program; +  add_ref(mutex_program);    end_class("mutex", 0);       START_NEW_PROGRAM_ID(THREAD_CONDITION);    ADD_STORAGE(struct pike_cond); -  +  PIKE_MAP_VARIABLE("_mutex", OFFSETOF(pike_cond, mutex_obj), +  tObjIs_THREAD_MUTEX, T_OBJECT, ID_PROTECTED|ID_PRIVATE); +  ADD_FUNCTION("create", f_cond_create, +  tFunc(tOr(tObjIs_THREAD_MUTEX, tVoid), tVoid), +  ID_PROTECTED);    ADD_FUNCTION("wait",f_cond_wait,    tOr(tFunc(tObjIs_THREAD_MUTEX_KEY tOr3(tVoid, tIntPos, tFloat),    tVoid),    tFunc(tObjIs_THREAD_MUTEX_KEY tIntPos tIntPos, tVoid)),0);    ADD_FUNCTION("signal",f_cond_signal,tFunc(tNone,tVoid),0);    ADD_FUNCTION("broadcast",f_cond_broadcast,tFunc(tNone,tVoid),0);    set_init_callback(init_cond_obj);    set_exit_callback(exit_cond_obj);    end_class("condition", 0);   
pike.git/src/threads.c:3543:       destruct(backend_thread_obj);    free_object(backend_thread_obj);    backend_thread_obj = NULL;       Pike_interpreter_pointer = original_interpreter;       destruct_objects_to_destruct_cb();    }    +  if(mutex_program) +  { +  free_program(mutex_program); +  mutex_program = NULL; +  } +     if(mutex_key)    {    free_program(mutex_key);    mutex_key=0;    }       if(thread_local_prog)    {    free_program(thread_local_prog);    thread_local_prog=0;