From 78ae7eb0bdb5fe79496a431b16b46ec0f1340d30 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 29 Mar 2010 11:31:08 +0200 Subject: [PATCH] Add support for non-recursive mutexes. 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 | 2 +- src/print.c | 6 +++++- src/thread.c | 26 ++++++++++++++++++++------ src/thread.h | 6 ++++++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/lisp.h b/src/lisp.h index 8b7737831be..c2847b168c5 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -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); diff --git a/src/print.c b/src/print.c index 79020012c08..e9bd1f80ddd 100644 --- a/src/print.c +++ b/src/print.c @@ -2174,7 +2174,11 @@ print_object (obj, printcharfun, escapeflag) } else if (MUTEXP (obj)) { - strout ("#", -1, -1, printcharfun, 0); + struct Lisp_Mutex *mutex = XMUTEX (obj); + strout ("#recursive) + strout (" recursive", -1, -1, printcharfun, 0); + PRINTCHAR ('>'); } else { diff --git a/src/thread.c b/src/thread.c index 74ad6c2376e..151bb0ea6be 100644 --- a/src/thread.c +++ b/src/thread.c @@ -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 diff --git a/src/thread.h b/src/thread.h index dc9ad12f72a..8fb0cb8bc20 100644 --- a/src/thread.h +++ b/src/thread.h @@ -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 -- 2.11.4.GIT