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.235 2004/04/26 16:21:19 mast Exp $ + || $Id: threads.c,v 1.236 2004/05/01 12:32:18 mast Exp $   */      #ifndef CONFIGURE_TEST   #include "global.h" - RCSID("$Id: threads.c,v 1.235 2004/04/26 16:21:19 mast Exp $"); + RCSID("$Id: threads.c,v 1.236 2004/05/01 12:32:18 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:1122:    *! to unspecified locking order and therefore a risk for deadlocks.    *! @endint    *!    *! @note    *! 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.    *! +  *! @note +  *! Pike 7.4 and earlier destructed any outstanding lock when the +  *! mutex was destructed, but threads waiting in @[lock] still got +  *! functioning locks as discussed above. This is inconsistent no +  *! matter how you look at it, so it was changed in 7.6. The old +  *! behavior is retained in compatibility mode for applications that +  *! explicitly destruct mutexes to unlock them. +  *!    *! @seealso    *! @[trylock()]    */   void f_mutex_lock(INT32 args)   {    struct mutex_storage *m;    struct object *o;    INT_TYPE type;       DEBUG_CHECK_THREAD();
pike.git/src/threads.c:1364:    * lock we need to double it to a broadcast. The last thread    * that stops waiting will destroy m->condition. */    co_broadcast (&m->condition);    }    }    else    co_destroy(& m->condition);   #endif   }    + void exit_mutex_obj_compat_7_4(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)); +  +  if(key) { +  m->key=0; +  destruct(key); /* Will destroy m->condition if m->num_waiting is zero. */ +  } +  else { + #ifdef PIKE_DEBUG +  if (m->num_waiting) +  Pike_error ("key/num_waiting confusion.\n"); + #endif +  co_destroy(& m->condition); +  } + } +    /*! @endclass    */      /*! @class MutexKey    *!    *! Objects of this class are returned by @[Mutex()->lock()]    *! and @[Mutex()->trylock()]. They are also passed as arguments    *! to @[Condition()->wait()].    *!    *! As long as they are held, the corresponding mutex will be locked.
pike.git/src/threads.c:2049:    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);    set_init_callback(init_mutex_obj);    set_exit_callback(exit_mutex_obj);    end_class("mutex", 0);    +  START_NEW_PROGRAM_ID(THREAD_MUTEX_COMPAT_7_4); +  ADD_STORAGE(struct mutex_storage); +  ADD_FUNCTION("lock",f_mutex_lock, +  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); +  set_init_callback(init_mutex_obj); +  set_exit_callback(exit_mutex_obj_compat_7_4); +  end_class("mutex_compat_7_4", 0); +     START_NEW_PROGRAM_ID(THREAD_CONDITION);    ADD_STORAGE(COND_T);    ADD_FUNCTION("wait",f_cond_wait,    tFunc(tObjIs_THREAD_MUTEX_KEY,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);