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.234 2004/04/26 15:45:43 mast Exp $ + || $Id: threads.c,v 1.235 2004/04/26 16:21:19 mast Exp $   */      #ifndef CONFIGURE_TEST   #include "global.h" - RCSID("$Id: threads.c,v 1.234 2004/04/26 15:45:43 mast Exp $"); + RCSID("$Id: threads.c,v 1.235 2004/04/26 16:21:19 mast Exp $");      PMOD_EXPORT int num_threads = 1;   PMOD_EXPORT int threads_disabled = 0;   #endif /* !CONFIGURE_TEST */      /* #define PICKY_MUTEX */      #ifdef _REENTRANT      #ifndef CONFIGURE_TEST
pike.git/src/threads.c:1099:    *! that locked them. In Pike any thread can unlock a locked mutex.    */      /*! @decl MutexKey lock()    *! @decl MutexKey lock(int type)    *!    *! This function attempts to lock the mutex. If the mutex is already    *! locked by a different thread the current thread will sleep until the    *! mutex is unlocked. The value returned is the 'key' to the lock. When    *! the key is destructed or has no more references the mutex will -  *! automatically be unlocked. The key will also be destructed if the mutex -  *! is destructed. +  *! automatically be unlocked.    *!    *! The @[type] argument specifies what @[lock()] should do if the    *! mutex is already locked by this thread:    *! @int    *! @value 0    *! Throw an error.    *! @value 1    *! Sleep until the mutex is unlocked. Useful if some    *! other thread will unlock it.    *! @value 2    *! Return zero. This allows recursion within a locked region of    *! code, but in conjunction with other locks it easily leads    *! to unspecified locking order and therefore a risk for deadlocks.    *! @endint    *!    *! @note -  *! If the mutex is destructed while threads are waiting on it, it -  *! will continue to exist internally until the last thread has -  *! stopped waiting. The returned @[MutexKey] objects will behave as -  *! usual, but refer to the internal "zombie" mutex. +  *! If the mutex is destructed while it's locked or while threads are +  *! waiting on it, it will continue to exist internally until the last +  *! thread has stopped waiting and the last @[MutexKey] has +  *! disappeared, but further calls to the functions in this class will +  *! fail as is usual for destructed objects.    *!    *! @seealso    *! @[trylock()]    */   void f_mutex_lock(INT32 args)   {    struct mutex_storage *m;    struct object *o;    INT_TYPE type;   
pike.git/src/threads.c:1333:    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:%p\n", THIS_MUTEX));    + #ifndef PICKY_MUTEX +  if (key) { +  /* The last key will destroy m->condition in its exit hook. */ +  THREADS_FPRINTF(1, (stderr, "Destructed mutex is in use - delaying cleanup\n")); +  } +  else { + #ifdef PIKE_DEBUG +  if (m->num_waiting) +  Pike_error ("key/num_waiting confusion.\n"); + #endif +  co_destroy(& m->condition); +  } + #else    if(key) {    m->key=0; -  destruct(key); +  destruct(key); /* Will destroy m->condition if m->num_waiting is zero. */    if(m->num_waiting)    { -  THREADS_FPRINTF(1, (stderr, "DESTRUCTED MUTEX IS BEING WAITED ON\n")); - #ifdef PICKY_MUTEX +  THREADS_FPRINTF(1, (stderr, "Destructed mutex is being waited on.\n"));    /* 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 -  /* The last thread that stops waiting will destroy -  * m->condition. */ - #endif -  return; +     }    } -  +  else    co_destroy(& m->condition); -  + #endif   }      /*! @endclass    */      /*! @class MutexKey    *!    *! Objects of this class are returned by @[Mutex()->lock()]    *! and @[Mutex()->trylock()]. They are also passed as arguments    *! to @[Condition()->wait()].
pike.git/src/threads.c:1416:    if (THIS_KEY->owner_obj) {    free_object(THIS_KEY->owner_obj);    THIS_KEY->owner_obj=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); - #ifndef PICKY_MUTEX +     else if (!mutex_obj->prog)    co_destroy (&mut->condition); - #endif +     free_object(mutex_obj);    }   }      /*! @endclass    */      #define THIS_COND ((COND_T *)(CURRENT_STORAGE))      /*! @class Condition