extern gboolean start_gtk (int *argc, char ***argv);
extern void stop_gtk (void);
extern void run_gtk (unsigned long registry, double time);
+extern void yield_gtk (void);
extern gboolean gtk_time_slice_window_p (void);
extern void gtk_time_slice_window (gboolean open_p);
extern gboolean gtk_select_trace_p (void);
find-c-includes
c-enum-constant-values))
-(define-package (gtk thread)
- (parent (runtime thread))
- (files "thread")
- ;;(depends-on)
- (export ()
- stop-gtk-thread)
- (import (gtk gobject)
- run-gc-cleanups)
- (import (gtk main)
- run-gtk)
- (import (runtime primitive-io)
- select-registry-handle))
-
(define-package (gtk main)
(parent (gtk))
(files "main")
gtk-select-trace?
gtk-select-trace!))
+(define-package (gtk thread)
+ (parent (runtime thread))
+ (files "thread")
+ ;;(depends-on "main")
+ (export ()
+ stop-gtk-thread)
+ (import (gtk gobject)
+ run-gc-cleanups)
+ (import (gtk main)
+ run-gtk
+ yield-gtk)
+ (import (runtime primitive-io)
+ select-registry-handle))
+
(define-package (gtk event-viewer)
(parent (gtk))
(files "gtk-ev")
/* When to give up waiting. */
double time_limit;
+
+ /* TRUE when Scheme has a runnable thread. Set to FALSE at the
+ start of run_gtk. Set to TRUE by a callback that has made a
+ Scheme thread runnable. */
+ gboolean runnable;
};
typedef struct _SchemeSource SchemeSource;
double dtime = OS_real_time_clock ();
int timeo = src->time_limit - dtime;
if (timeo <= 0
+ || src->runnable
|| pending_interrupts_p ()
|| OS_process_any_status_change ())
{
if (timeo > 0)
{
outf_console (";scheme_source_prepare: %s\n",
- pending_interrupts_p ()
- ? "interrupt" : "subprocess");
+ src->runnable ? "thread"
+ : pending_interrupts_p () ? "interrupt"
+ : "subprocess");
}
else
{
/* Return TRUE when ready to dispatch (after the poll). */
SchemeSource * src = (SchemeSource *)source;
- double time = OS_real_time_clock ();
- if (time > src->time_limit
- || pending_io (src)
+ if (src->runnable
|| pending_interrupts_p ()
- || OS_process_any_status_change ())
+ || OS_process_any_status_change ()
+ || pending_io (src))
{
- if (tracing_gtk_select
- && (time > src->time_limit
- || pending_interrupts_p ()
- || OS_process_any_status_change ()))
+ if (tracing_gtk_select)
{
outf_console (";scheme_source_check: %s\n",
- pending_interrupts_p () ? "interrupt"
+ src->runnable ? "thread"
+ : pending_interrupts_p () ? "interrupt"
: OS_process_any_status_change () ? "subprocess"
- : time > src->time_limit ? "timeout"
: "i/o ready");
outf_flush_console ();
}
g_source_new (&scheme_source_funcs, sizeof (SchemeSource));
scheme_source->gpollfds = NULL;
scheme_source->time_limit = 0.0;
+ scheme_source->runnable = FALSE;
g_source_attach ((GSource *) scheme_source, NULL);
}
clear_registry (source);
source->time_limit = time;
+ source->runnable = FALSE;
source->gpollfds = new;
{
GMainContext * context = g_source_get_context ((GSource *)source);
abort_to_c ();
/*NOTREACHED*/
}
+
+void
+yield_gtk (void)
+{
+ scheme_source->runnable = TRUE;
+}
\f
/* Gtk Select Registries -- GSLists of GPollFDs. */
(gtk-thread-loop))))))
(detach-thread gtk-thread))
-(define (no-threads-nor-timers)
- ;; Wake up once a minute, just to see if you can...
- (+ (real-time-clock) (* 60 1000)))
+(define-integrable (no-threads-nor-timers)
+ ;; Wake up once a minute, just to see if we can.
+ (let ((t (+ (real-time-clock) (* 60 1000))))
+ (%trace ";no-thread-nor-timers: wake up for no reason at "t"\n")
+ t))
+
+(define (maybe-yield-gtk)
+ ;; Used by callbacks that may have made threads runnable.
+ (%trace ";maybe-yield-gtk "(thread/next (current-thread)))
+ (if (thread/next (current-thread))
+ (yield-gtk)))
(define (exit-gtk-thread)
(let ((thread gtk-thread))