]> git.eshelyaron.com Git - emacs.git/commitdiff
Add support for non-recursive mutexes.
authorGiuseppe Scrivano <gscrivano@gnu.org>
Mon, 29 Mar 2010 09:31:08 +0000 (11:31 +0200)
committerGiuseppe Scrivano <gscrivano@gnu.org>
Mon, 29 Mar 2010 09:31:08 +0000 (11:31 +0200)
make-mutex accepts a new parameter, if the value is non nil then the
mutex is recursive; by default a non-recursive mutex is created.

src/lisp.h
src/print.c
src/thread.c
src/thread.h

index 8b7737831be12934a5470b96f4f41bf5a036fa9a..c2847b168c50c12ca57581b765e11d975152577c 100644 (file)
@@ -2375,7 +2375,7 @@ EXFUN (Fadd1, 1);
 EXFUN (Fsub1, 1);
 EXFUN (Fmake_variable_buffer_local, 1);
 
-EXFUN (Fmake_mutex, 0);
+EXFUN (Fmake_mutex, 1);
 EXFUN (Fmutex_lock, 1);
 EXFUN (Fmutex_unlock, 1);
 
index 79020012c08fd40bed7c075ee3b3eca8867fb8e9..e9bd1f80dddf6e1b65c10cd3c308b28f29da5763 100644 (file)
@@ -2174,7 +2174,11 @@ print_object (obj, printcharfun, escapeflag)
        }
       else if (MUTEXP (obj))
         {
-             strout ("#<mutex>", -1, -1, printcharfun, 0);
+          struct Lisp_Mutex *mutex = XMUTEX (obj);
+          strout ("#<mutex", -1, -1, printcharfun, 0);
+          if (mutex->recursive)
+            strout (" recursive", -1, -1, printcharfun, 0);
+          PRINTCHAR ('>');
         }
       else
        {
index 74ad6c2376ebbccae48e8d5e28eda0e303f8e3bd..151bb0ea6be6a1cd06e1ac7d9d04e59546612440 100644 (file)
@@ -346,13 +346,17 @@ user_thread_p (void)
   return 0;
 }
 
-DEFUN ("make-mutex", Fmake_mutex, Smake_mutex, 0, 0, 0,
-       doc: /* Make a mutex.  */)
-     ()
+DEFUN ("make-mutex", Fmake_mutex, Smake_mutex, 0, 1, 0,
+       doc: /* Make a mutex.  If RECURSIVE is nil the mutex is not recursive
+             and can be locked once.  */)
+     (recursive)
+     Lisp_Object recursive;
 {
   Lisp_Object ret;
   struct Lisp_Mutex *mutex = allocate_mutex ();
   mutex->owner = 0;
+  mutex->rec_counter = 0;
+  mutex->recursive = ! NILP (recursive);
   XSETMUTEX (ret, mutex);
   return ret;
 }
@@ -365,9 +369,11 @@ DEFUN ("mutex-lock", Fmutex_lock, Smutex_lock, 1, 1, 0,
   struct Lisp_Mutex *mutex = XMUTEX (val);
   while (1)
     {
-      if (mutex->owner == 0 || mutex->owner == pthread_self ())
+      if (mutex->owner == 0
+          || (mutex->recursive && mutex->owner == pthread_self ()))
         {
           mutex->owner = pthread_self ();
+          mutex->rec_counter++;
           return Qt;
         }
 
@@ -383,7 +389,15 @@ DEFUN ("mutex-unlock", Fmutex_unlock, Smutex_unlock, 1, 1, 0,
      Lisp_Object val;
 {
   struct Lisp_Mutex *mutex = XMUTEX (val);
-  mutex->owner = 0;
+
+  if (mutex->owner != pthread_self () || mutex->rec_counter == 0)
+    return Qnil;
+
+  mutex->rec_counter--;
+
+  if (mutex->rec_counter == 0)
+    mutex->owner = 0;
+
   return Qt;
 }
 
@@ -448,7 +462,7 @@ init_threads_once (void)
   primary_thread.func = Qnil;
   primary_thread.initial_specpdl = Qnil;
   XSETPVECTYPE (&primary_thread, PVEC_THREAD);
-  minibuffer_mutex = Fmake_mutex ();
+  minibuffer_mutex = Fmake_mutex (Qnil);
 }
 
 void
index dc9ad12f72ab7c49d10bcf1a2b5f95fedb790e9a..8fb0cb8bc20c867b744fe8c9606c331bbb160d9a 100644 (file)
@@ -6,8 +6,14 @@ struct Lisp_Mutex
 
   struct Lisp_Vector *v_next;
 
+  /* Is the mutex recursive?  */
+  int recursive;
+
   /* Thread that owns the mutex.  */
   pthread_t owner;
+
+  /* Number of times it was recursively owned.  */
+  unsigned int rec_counter;
 };
 
 struct thread_state