Subject: bug#15801: 24.3.50; bar scrolling freezes gtk emacs

From: Jarek Czekalski <[email-masked]>
Date: Sat, 30 Nov 2013 18:04:05 +0100

Jan,

Thank you for the attempt. It must be very difficult to work on it, 
without being able to reproduce as easily as it happens on my side.

The attempt failed. The code you inserted is never reached. Even if I 
make it reachable (reducing the condition to "interrupt_input" or make 
it executed always), still hanging occurs with the same ease.

What you fix is probably introduced a very long time ago (before 
r31171), with copy and paste programming method. This could be more 
readable as part of STOP_POLLING and
RESUME_POLLING macros (or maybe even part of stop_polling?). I prepared 
a patch making it so. This has nothing to do with copyright, the idea is 
yours, so please don't credit me in this case. Anyway I posted an 
assignment 2 weeks ago, maybe it arrived already. This is only code 
rearrangement, without any behavior change, so you may skip it as well.

Further discoveries:
1. Making unrequest_sigio never called does not remove the freeze (in 
one attempt it even appeared sooner)
2. Placing STOP_POLLING (patched, containing unrequest) at the very 
beginning of redisplay_internal seems to make no detectable change
Maybe one of these changes would make it reproducable at your box?

When I was debugging threading issues in Java I used a function 
debugDelay(int n) which simulated computations. This could be inserted 
in various places to make bugs reproducable by anyone. Of course finding 
the right place(s) is truly difficult. Maybe this method could be 
applied here. If we don't have such a helper function, I can write it. 
It must trick the compiler, so it not optimize the fictional loop. But I 
can't help in finding the right place to insert it, because I reproduce 
it in a blink of an eye.

Jarek

=== modified file 'src/xdisp.c'
--- src/xdisp.c	2013-11-30 14:03:53 +0000
+++ src/xdisp.c	2013-11-30 16:04:59 +0000
@@ -13119,13 +13119,28 @@
     }
 }
 
-#define STOP_POLLING					\
-do { if (! polling_stopped_here) stop_polling ();	\
-       polling_stopped_here = 1; } while (0)
+#define STOP_POLLING                                      \
+do {                                                      \
+  if (! polling_stopped_here) stop_polling ();            \
+  polling_stopped_here = 1;                               \
+  /* Prevent various kinds of signals during display      \
+     update.  stdio is not robust about handling          \
+     signals, which can cause an apparent I/O error.  */  \
+  if (interrupt_input)                                    \
+    unrequest_sigio ();                                   \
+} while (0)
 
-#define RESUME_POLLING					\
-do { if (polling_stopped_here) start_polling ();	\
-       polling_stopped_here = 0; } while (0)
+#define RESUME_POLLING                                                 \
+do {                                                                   \
+  if (polling_stopped_here) start_polling ();	                       \
+  polling_stopped_here = 0;                                            \
+  /* Start SIGIO interrupts coming again.  Having them off during the  \
+     code above makes it less likely one will discard output, but not  \
+     impossible, since there might be stuff in the system buffer here. \
+     But it is much hairier to try to do anything about that.  */      \
+  if (interrupt_input)                                                 \
+    request_sigio ();                                                  \
+} while (0)

 /* Perhaps in the future avoid recentering windows if it
@@ -13627,11 +13642,6 @@
 			goto retry_frame;
 		    }
 
-		  /* Prevent various kinds of signals during display
-		     update.  stdio is not robust about handling
-		     signals, which can cause an apparent I/O error.  */
-		  if (interrupt_input)
-		    unrequest_sigio ();
 		  STOP_POLLING;
 
 		  pending |= update_frame (f, 0, 0);
@@ -13684,11 +13694,6 @@
       if (sf->fonts_changed)
 	goto retry;
 
-      /* Prevent various kinds of signals during display update.
-	 stdio is not robust about handling signals,
-	 which can cause an apparent I/O error.  */
-      if (interrupt_input)
-	unrequest_sigio ();
       STOP_POLLING;
 
       if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
@@ -13761,12 +13766,6 @@
       windows_or_buffers_changed = 0;
     }
 
-  /* Start SIGIO interrupts coming again.  Having them off during the
-     code above makes it less likely one will discard output, but not
-     impossible, since there might be stuff in the system buffer here.
-     But it is much hairier to try to do anything about that.  */
-  if (interrupt_input)
-    request_sigio ();
   RESUME_POLLING;
 
   /* If a frame has become visible which was not before, redisplay
@@ -13819,8 +13818,6 @@
 #endif /* HAVE_WINDOW_SYSTEM */
 
  end_of_redisplay:
-  if (interrupt_input && interrupts_deferred)
-    request_sigio ();
 
   unbind_to (count, Qnil);
   RESUME_POLLING;