From 72dff70397de65d3d079ed53d932d98fcabf4364 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sat, 13 Feb 2010 01:09:42 +0100 Subject: [PATCH] Handle exclusive access to the minibuffer using a mutex, remove inhibit-yield --- lisp/subr.el | 16 ++++++++-------- src/fns.c | 5 ++--- src/keyboard.c | 4 ++-- src/lisp.h | 7 +++++++ src/minibuf.c | 4 ++-- src/thread.c | 34 ++++++++-------------------------- src/thread.h | 4 ---- src/xdisp.c | 4 ++-- 8 files changed, 31 insertions(+), 47 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index f362f27b515..83136f6ce21 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1839,7 +1839,7 @@ some sort of escape sequence, the ambiguity is resolved via `read-key-delay'." ;; for more input to decide how to interpret the ;; current input. (throw 'read-key keys))))))) - (with-no-threads + (with-critical-section minibuffer-mutex (unwind-protect (progn (use-global-map read-key-empty-map) @@ -1868,7 +1868,7 @@ for numeric input." or the octal character code. RET terminates the character code and is discarded; any other non-digit terminates the character code and is then used as input.")) - (with-no-threads + (with-critical-section minibuffer-mutex (setq char (read-event (and prompt (format "%s-" prompt)) t))) (if inhibit-quit (setq quit-flag nil))) ;; Translate TAB key into control-I ASCII character, and so on. @@ -1926,7 +1926,7 @@ then it returns nil if the user types C-g, but quit-flag remains set. Once the caller uses the password, it can erase the password by doing (clear-string STRING)." (with-local-quit - (with-no-threads + (with-critical-section minibuffer-mutex (if confirm (let (success) (while (not success) @@ -1996,7 +1996,7 @@ by doing (clear-string STRING)." "Read a numeric value in the minibuffer, prompting with PROMPT. DEFAULT specifies a default value to return if the user just types RET. The value of DEFAULT is inserted into PROMPT." - (with-no-threads + (with-critical-section minibuffer-mutex (let ((n nil)) (when default (setq prompt @@ -2653,13 +2653,13 @@ Similar to `call-process-shell-command', but calls `process-file'." ;;;; Lisp macros to do various things temporarily. -(defmacro with-no-threads (&rest body) - "Disable temporarily other threads to be executed." +(defmacro with-critical-section (mutex &rest body) + "Execute code in a critical section." (declare (indent 1) (debug t)) `(unwind-protect - (progn (inhibit-yield t) + (progn (mutex-lock mutex) ,@body) - (inhibit-yield nil))) + (mutex-unlock mutex))) (defmacro with-current-buffer (buffer-or-name &rest body) "Execute the forms in BODY with BUFFER-OR-NAME temporarily current. diff --git a/src/fns.c b/src/fns.c index ed2dcc1cc98..5ec367c944f 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2738,10 +2738,9 @@ is nil, and `use-dialog-box' is non-nil. */) Lisp_Object ret; int count = SPECPDL_INDEX (); - Finhibit_yield (Qt); - record_unwind_protect (Finhibit_yield, Qnil); + Fmutex_lock (minibuffer_mutex); + record_unwind_protect (Fmutex_unlock, minibuffer_mutex); ret = Fyes_or_no1 (prompt); - Finhibit_yield (Qnil); unbind_to (count, Qnil); return ret; } diff --git a/src/keyboard.c b/src/keyboard.c index 8200a2fd0ca..15fe57094dc 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -10329,8 +10329,8 @@ will read just one key sequence. */) if (display_hourglass_p) cancel_hourglass (); #endif - Finhibit_yield (Qt); - record_unwind_protect (Finhibit_yield, Qnil); + Fmutex_lock (minibuffer_mutex); + record_unwind_protect (Fmutex_unlock, minibuffer_mutex); i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])), prompt, ! NILP (dont_downcase_last), diff --git a/src/lisp.h b/src/lisp.h index d4392bc7eab..0c4bb15551f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1960,6 +1960,8 @@ extern struct backtrace *backtrace_list; extern Lisp_Object memory_signal_data; +extern Lisp_Object minibuffer_mutex; + /* Check quit-flag and quit if it is non-nil. Typing C-g does not directly cause a quit; it only sets Vquit_flag. So the program needs to do QUIT at times when it is safe to quit. @@ -2373,6 +2375,11 @@ EXFUN (Fadd1, 1); EXFUN (Fsub1, 1); EXFUN (Fmake_variable_buffer_local, 1); +EXFUN (Fmake_mutex, 0); +EXFUN (Fmutex_lock, 1); +EXFUN (Fmutex_unlock, 1); + + extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); extern Lisp_Object *find_variable_location (Lisp_Object *); extern Lisp_Object ensure_thread_local (Lisp_Object *); diff --git a/src/minibuf.c b/src/minibuf.c index c6f62f52e26..6b0038c608c 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -585,8 +585,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag, minibuf_save_list)))))); - Finhibit_yield (Qt); - record_unwind_protect (Finhibit_yield, Qnil); + Fmutex_lock (minibuffer_mutex); + record_unwind_protect (Fmutex_unlock, minibuffer_mutex); record_unwind_protect (read_minibuf_unwind, Qnil); minibuf_level++; diff --git a/src/thread.c b/src/thread.c index 32d5f3fb49f..1165a9622cb 100644 --- a/src/thread.c +++ b/src/thread.c @@ -26,13 +26,13 @@ static struct thread_state *all_threads = &primary_thread; __thread struct thread_state *current_thread = &primary_thread; -static int inhibit_yield_counter = 0; - pthread_mutex_t global_lock; /* Used internally by the scheduler, it is the next that will be executed. */ static pthread_t next_thread; +Lisp_Object minibuffer_mutex; + /* Choose the next thread to be executed. */ static void thread_schedule () @@ -53,8 +53,7 @@ static inline void reschedule (char *end, int wait) { current_thread->stack_top = end; - if (!thread_inhibit_yield_p ()) - thread_schedule (); + thread_schedule (); if (next_thread != current_thread->pthread_id) pthread_cond_broadcast (&thread_cond); @@ -151,17 +150,10 @@ unmark_threads (void) unmark_byte_stack (iter->m_byte_stack_list); } -int -thread_inhibit_yield_p () -{ - return inhibit_yield_counter || interrupt_input_blocked || abort_on_gc; -} - static void thread_yield_callback (char *end, void *ignore) { - if (!thread_inhibit_yield_p ()) - reschedule (end, 1); + reschedule (end, 1); } void @@ -352,19 +344,6 @@ user_thread_p (void) return 0; } -DEFUN ("inhibit-yield", Finhibit_yield, Sinhibit_yield, 1, 1, 0, - doc: /* Inhibit the yield function. */) - (val) - Lisp_Object val; -{ - if (!EQ (val, Qnil)) - inhibit_yield_counter++; - else if (inhibit_yield_counter > 0) - inhibit_yield_counter--; - - return Qnil; -} - DEFUN ("make-mutex", Fmake_mutex, Smake_mutex, 0, 0, 0, doc: /* Make a mutex. */) () @@ -467,6 +446,7 @@ init_threads_once (void) primary_thread.func = Qnil; primary_thread.initial_specpdl = Qnil; XSETPVECTYPE (&primary_thread, PVEC_THREAD); + minibuffer_mutex = Fmake_mutex (); } void @@ -485,9 +465,11 @@ init_threads (void) void syms_of_threads (void) { + DEFVAR_LISP ("minibuffer-mutex", &minibuffer_mutex, + doc: /* Mutex for the minibuffer. */); + defsubr (&Srun_in_thread); defsubr (&Syield); - defsubr (&Sinhibit_yield); defsubr (&Smake_mutex); defsubr (&Smutex_lock); defsubr (&Smutex_unlock); diff --git a/src/thread.h b/src/thread.h index 41157d03dc3..dc9ad12f72a 100644 --- a/src/thread.h +++ b/src/thread.h @@ -145,8 +145,4 @@ extern int other_threads_p P_ ((void)); extern int user_thread_p P_ ((void)); -EXFUN (Finhibit_yield, 1); - -extern int thread_inhibit_yield_p P_ ((void)); - extern Lisp_Object thread_notify_kill_buffer (register struct buffer *b); diff --git a/src/xdisp.c b/src/xdisp.c index 3c90e6a357c..a6b0b04a6bc 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -11401,8 +11401,8 @@ redisplay_internal (preserve_echo_area) } } - Finhibit_yield (Qt); - record_unwind_protect (Finhibit_yield, Qnil); + Fmutex_lock (minibuffer_mutex); + record_unwind_protect (Fmutex_unlock, minibuffer_mutex); retry: if (!EQ (old_frame, selected_frame) -- 2.11.4.GIT