]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix point motion in cloned buffers
authorEli Zaretskii <eliz@gnu.org>
Mon, 12 Dec 2016 16:03:40 +0000 (18:03 +0200)
committerEli Zaretskii <eliz@gnu.org>
Mon, 12 Dec 2016 16:03:40 +0000 (18:03 +0200)
* 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
src/buffer.h
src/thread.c
test/src/thread-tests.el

index cea1ddb5ab3e36d749255a5d32824764eeacbea5..babfba3e65f93bf2a663cea34d1018aad1215919 100644 (file)
@@ -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;
index 21ad5e3bc0f97a9b8e8d76709797a5e64eae6731..854b5b5dd32f7df17fd760964b38c728314e9113 100644 (file)
@@ -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);
index 3e61723f0ab8229304b42f9dc18a2b603e71f744..6e9ca2e256b6eb967ad794cb7a4c69da683c472e 100644 (file)
@@ -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))
     {
index 4e7b052cba0e39a6dd55015e05f5085f3ec6b8b8..7261cda9fbb5955165cfc82e4ad0a5f5e0fc08da 100644 (file)
     :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