pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: threads.c,v 1.202 2004/04/23 19:35:28 grubba Exp $ + || $Id: threads.c,v 1.203 2004/04/23 19:40:14 mast Exp $   */      #include "global.h" - RCSID("$Id: threads.c,v 1.202 2004/04/23 19:35:28 grubba Exp $"); + RCSID("$Id: threads.c,v 1.203 2004/04/23 19:40:14 mast Exp $");      PMOD_EXPORT int num_threads = 1;   PMOD_EXPORT int threads_disabled = 0;      /* #define PICKY_MUTEX */      #ifdef _REENTRANT   #include "threads.h"   #include "array.h"   #include "mapping.h"
pike.git/src/threads.c:1255:   void init_mutex_obj(struct object *o)   {    co_init(& THIS_MUTEX->condition);    THIS_MUTEX->key=0;    THIS_MUTEX->num_waiting = 0;   }      void exit_mutex_obj(struct object *o)   {    struct mutex_storage *m = THIS_MUTEX; +  struct object *key = m->key;       THREADS_FPRINTF(1, (stderr, "DESTROYING MUTEX m:%08x\n",    (unsigned int)m));    -  if(m->key) { -  destruct(m->key); +  if(key) {    m->key=0; -  +  destruct(key);    if(m->num_waiting)    {    THREADS_FPRINTF(1, (stderr, "DESTRUCTED MUTEX IS BEING WAITED ON\n"));   #ifdef PICKY_MUTEX    /* exit_mutex_key_obj has already signalled, but since the    * waiting threads will throw an error instead of making a new    * lock we need to double it to a broadcast. The last thread    * that stops waiting will destroy m->condition. */    co_broadcast (&m->condition);   #else
pike.git/src/threads.c:1305:   void exit_mutex_key_obj(struct object *o)   {    THREADS_FPRINTF(1, (stderr, "UNLOCK k:%08x m:(%08x) t:%08x o:%08x\n",    (unsigned int)THIS_KEY,    (unsigned int)THIS_KEY->mut,    (unsigned int)Pike_interpreter.thread_id,    (unsigned int)THIS_KEY->owner));    if(THIS_KEY->mut)    {    struct mutex_storage *mut = THIS_KEY->mut; +  struct object *mutex_obj;      #ifdef PIKE_DEBUG    /* Note: mut->key can be NULL if our corresponding mutex    * has been destructed.    */    if(mut->key && (mut->key != o))    Pike_fatal("Mutex unlock from wrong key %p != %p!\n", mut->key, o);   #endif    mut->key=0;    if (THIS_KEY->owner) {    free_object(THIS_KEY->owner);    THIS_KEY->owner=0;    }    THIS_KEY->mut=0;    THIS_KEY->initialized=0; -  +  mutex_obj = THIS_KEY->mutex_obj; +  THIS_KEY->mutex_obj = NULL;    if (mut->num_waiting) -  co_signal(& mut->condition); +  co_signal(&mut->condition);   #ifndef PICKY_MUTEX -  else if (!THIS_KEY->mutex_obj->prog) +  else if (!mutex_obj->prog)    co_destroy (&mut->condition);   #endif -  free_object (THIS_KEY->mutex_obj); -  THIS_KEY->mutex_obj = NULL; +  free_object(mutex_obj);    }   }      #define THIS_COND ((COND_T *)(CURRENT_STORAGE))      /*! @class Condition    *!    *! Implementation of condition variables.    *!    *! Condition variables are used by threaded programs
pike.git/src/threads.c:1375:    *! In Pike 7.2 and earlier it was possible to call @[wait()]    *! without arguments. This possibility was removed in later    *! versions since it unavoidably leads to programs with races    *! and/or deadlocks.    *!    *! @seealso    *! @[Mutex->lock()]    */   void f_cond_wait(INT32 args)   { -  struct object *key; +  struct object *key, *mutex_obj;    struct mutex_storage *mut;    COND_T *c;       if(threads_disabled)    Pike_error("Cannot wait for conditions when threads are disabled!\n");       get_all_args("condition->wait", args, "%o", &key);       if ((key->prog != mutex_key) ||    (!(OB2KEY(key)->initialized)) ||
pike.git/src/threads.c:1398:    }       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; -  mut->num_waiting++; +  OB2KEY(key)->mutex_obj = NULL;    co_signal(& mut->condition);       /* Wait and allow mutex operations */    SWAP_OUT_CURRENT_THREAD();    co_wait_interpreter(c);    SWAP_IN_CURRENT_THREAD();       /* Lock mutex */ -  +  mut->num_waiting++;    while(mut->key) {    SWAP_OUT_CURRENT_THREAD();    co_wait_interpreter(& mut->condition);    SWAP_IN_CURRENT_THREAD();    check_threads_etc();    }    mut->key=key;    OB2KEY(key)->mut=mut; -  +  OB2KEY(key)->mutex_obj = mutex_obj;    mut->num_waiting--;    -  + #ifdef PICKY_MUTEX +  if (!mutex_obj->prog) { +  if (!m->num_waiting) +  co_destroy (&m->condition); +  Pike_error ("Mutex was destructed while waiting for lock.\n"); +  } + #endif +     pop_stack();    return;   }      /*! @decl void signal()    *!    *! @[signal()] wakes up one of the threads currently waiting for the    *! condition.    *!    *! @note