Signal handlers can now make scheme_source runnable.
authorMatt Birkholz <matt@birkholz.chandler.az.us>
Sun, 31 Jul 2011 23:47:44 +0000 (16:47 -0700)
committerMatt Birkholz <matt@birkholz.chandler.az.us>
Sun, 31 Jul 2011 23:47:44 +0000 (16:47 -0700)
Previously the mask was always gc-only courtesy of call-alien, thus
pending_interrupts_p() was never true.  This was masked by the select
timeout which also makes scheme_source runnable.  Now that run-gtk
takes a timeout of -1, scheme_source_check needs to ignore the mask.

src/gtk/gtkio.c.stay

index deb35e234256bee661b57206b65cde37a30bab53..2fcbb0e1ebbd72e193b5e1a9f8c97477cf8319b3 100644 (file)
@@ -77,6 +77,7 @@ static void set_registry (SchemeSource * source, GSList * new, double time);
 static SchemeSource * scheme_source = NULL;
 static gboolean tracing_gtk_select = 0;
 static void trace (const char *format, ...);
+static gboolean interrupt_p (void);
 static GSList * gtk_registry (select_registry_t registry);
 
 static int slice_counter = 0;
@@ -100,6 +101,22 @@ trace (const char * format, ...)
   va_end (args);
 }
 
+static gboolean
+interrupt_p (void)
+{
+  /* Ignores the INT_MASK, which is interrupt-mask/gc-ok per
+     call-alien.  That mask keeps callbacks from wandering onto other
+     threads.  Ignoring it allows the scheme_source to return to the
+     gtk-thread, where call-alien will restore gtk-thread's mask,
+     unmasking whatever interrupt was pending (assuming gtk-thread
+     runs with all interrupts unmasked). */
+
+  /* return (INTERRUPT_PENDING_P (INT_Mask)); */
+  /* return (((PENDING_INTERRUPTS ()) & (INT_Mask)) != 0); */
+  /* return ((((GET_INT_MASK & GET_INT_CODE)) & (INT_Mask)) != 0); */
+  return (GET_INT_CODE);
+}
+
 static gboolean
 scheme_source_prepare (GSource * source, gint * timeout)
 {
@@ -111,12 +128,12 @@ scheme_source_prepare (GSource * source, gint * timeout)
   SchemeSource * src = (SchemeSource *)source;
 
   if (src->runnable
-      || pending_interrupts_p ()
+      || interrupt_p ()
       || OS_process_any_status_change ())
     {
       trace (";scheme_source_prepare: ready (%s)\n",
             src->runnable ? "thread"
-            : pending_interrupts_p () ? "interrupt"
+            : interrupt_p () ? "interrupt"
             : "subprocess");
       *timeout = 0;
       return (TRUE);
@@ -160,13 +177,13 @@ scheme_source_check (GSource * source)
 
   if (src->time_limit == 0.0
       || src->runnable
-      || pending_interrupts_p ()
+      || interrupt_p ()
       || OS_process_any_status_change ()
       || pending_io (src))
     {
       trace (";scheme_source_check: ready (%s)\n",
             src->runnable ? "thread"
-            : pending_interrupts_p () ? "interrupt"
+            : interrupt_p () ? "interrupt"
             : OS_process_any_status_change () ? "subprocess"
             : src->time_limit == 0.0 ? "" : "i/o");
       return (TRUE);