From a416e1d6c111527205f3583c8d201bf95af6fa20 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 12 Dec 2016 18:03:40 +0200 Subject: [PATCH] Fix point motion in cloned buffers * src/thread.c (post_acquire_global_lock): Call set_buffer_internal_2 instead of tricking set_buffer_internal_1 into resetting the current buffer even if it didn't change. This avoids bug#25165, caused by failing to record the modified values of point and mark, because current_buffer was set to NULL. Also, don't bother re-setting the buffer if there was no thread switch, as that just wastes cycles. * src/buffer.c (set_buffer_internal_2): New function, with most of the body of set_buffer_internal_1, but without the test for B being identical to the current buffer. (set_buffer_internal_1): Call set_buffer_internal_2 if B is not identical to the current buffer. * src/buffer.h (set_buffer_internal_2): Add prototype. * test/src/thread-tests.el (thread-sticky-point): New test. --- src/buffer.c | 14 +++++++++++--- src/buffer.h | 1 + src/thread.c | 11 +++++------ test/src/thread-tests.el | 12 +++++++++++- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index cea1ddb5ab3..babfba3e65f 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2033,9 +2033,6 @@ DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0, void set_buffer_internal_1 (register struct buffer *b) { - register struct buffer *old_buf; - register Lisp_Object tail; - #ifdef USE_MMAP_FOR_BUFFERS if (b->text->beg == NULL) enlarge_buffer_text (b, 0); @@ -2044,6 +2041,17 @@ set_buffer_internal_1 (register struct buffer *b) if (current_buffer == b) return; + set_buffer_internal_2 (b); +} + +/* Like set_buffer_internal_1, but doesn't check whether B is already + the current buffer. Called upon switch of the current thread, see + post_acquire_global_lock. */ +void set_buffer_internal_2 (register struct buffer *b) +{ + register struct buffer *old_buf; + register Lisp_Object tail; + BUFFER_CHECK_INDIRECTION (b); old_buf = current_buffer; diff --git a/src/buffer.h b/src/buffer.h index 21ad5e3bc0f..854b5b5dd32 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -1082,6 +1082,7 @@ extern void recenter_overlay_lists (struct buffer *, ptrdiff_t); extern ptrdiff_t overlay_strings (ptrdiff_t, struct window *, unsigned char **); extern void validate_region (Lisp_Object *, Lisp_Object *); extern void set_buffer_internal_1 (struct buffer *); +extern void set_buffer_internal_2 (struct buffer *); extern void set_buffer_temp (struct buffer *); extern Lisp_Object buffer_local_value (Lisp_Object, Lisp_Object); extern void record_buffer (Lisp_Object); diff --git a/src/thread.c b/src/thread.c index 3e61723f0ab..6e9ca2e256b 100644 --- a/src/thread.c +++ b/src/thread.c @@ -55,7 +55,6 @@ release_global_lock (void) static void post_acquire_global_lock (struct thread_state *self) { - Lisp_Object buffer; struct thread_state *prev_thread = current_thread; /* Do this early on, so that code below could signal errors (e.g., @@ -71,12 +70,12 @@ post_acquire_global_lock (struct thread_state *self) if (prev_thread != NULL) unbind_for_thread_switch (prev_thread); rebind_for_thread_switch (); - } - /* We need special handling to re-set the buffer. */ - XSETBUFFER (buffer, self->m_current_buffer); - self->m_current_buffer = 0; - set_buffer_internal (XBUFFER (buffer)); + /* Set the new thread's current buffer. This needs to be done + even if it is the same buffer as that of the previous thread, + because of thread-local bindings. */ + set_buffer_internal_2 (current_buffer); + } if (!NILP (current_thread->error_symbol)) { diff --git a/test/src/thread-tests.el b/test/src/thread-tests.el index 4e7b052cba0..7261cda9fbb 100644 --- a/test/src/thread-tests.el +++ b/test/src/thread-tests.el @@ -221,8 +221,18 @@ :group 'widget-faces)) (ert-deftest thread-errors () - "Test what happens when a thread signals an error." + "Test what happens when a thread signals an error." (should (threadp (make-thread #'call-error "call-error"))) (should (threadp (make-thread #'thread-custom "thread-custom")))) +(ert-deftest thread-sticky-point () + "Test bug #25165 with point movement in cloned buffer." + (with-temp-buffer + (insert "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") + (goto-char (point-min)) + (clone-indirect-buffer nil nil) + (forward-char 20) + (sit-for 1) + (should (= (point) 21)))) + ;;; threads.el ends here -- 2.11.4.GIT