From ae4e85a6a77bde5d3237f6b962b26e3476cebcff Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 23 Oct 2017 05:57:03 -0700 Subject: [PATCH] evt:struct with unsafe-poller: skip sleep if poll reports ready Intended to fix racket/gui#80 --- pkgs/racket-doc/scribblings/foreign/schedule.scrbl | 7 ++++--- racket/src/racket/src/struct.c | 13 +++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-doc/scribblings/foreign/schedule.scrbl b/pkgs/racket-doc/scribblings/foreign/schedule.scrbl index e8a8dad361..391d9c9268 100644 --- a/pkgs/racket-doc/scribblings/foreign/schedule.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/schedule.scrbl @@ -35,9 +35,10 @@ an event to replace @racket[_evt] (often just @racket[_evt] itself) if When the thread scheduler has determined that the Racket process should sleep until an external event or timeout, then @racket[poll] is called with a non-@racket[#f] second argument, @racket[_wakeups]. In -that case, the result must always be @racket[(values #f _evt)]. In -addition to returning the requires values, @racket[poll] can call -@racket[unsafe-poll-ctx-fd-wakeup], +that case, if the first result value is a list, then the sleep will be +canceled, but the list is not recorded as the result (and @racket[poll] +most likely will be called again). In addition to returning a @racket[#f] initial +value, @racket[poll] can call @racket[unsafe-poll-ctx-fd-wakeup], @racket[unsafe-poll-ctx-eventmask-wakeup], and/or @racket[unsafe-poll-ctx-milliseconds-wakeup] on @racket[_wakeups] to register wakeup triggers.} diff --git a/racket/src/racket/src/struct.c b/racket/src/racket/src/struct.c index 1b757b6197..aecb666bc1 100644 --- a/racket/src/racket/src/struct.c +++ b/racket/src/racket/src/struct.c @@ -1753,14 +1753,23 @@ void evt_struct_needs_wakeup(Scheme_Object *o, void *fds) v = scheme_struct_type_property_ref(evt_property, o); if (SCHEME_POLLERP(v)) { - Scheme_Object *a[2], *e; + Scheme_Object *a[2], *e, *r; scheme_start_in_scheduler(); a[0] = o; e = scheme_make_cptr(fds, scheme_false); a[1] = e; - _scheme_apply_multi(SCHEME_POLLER_PROC(v), 2, a); + r = _scheme_apply_multi(SCHEME_POLLER_PROC(v), 2, a); scheme_end_in_scheduler(); + + /* If event claims to be ready, then cancel the sleep: */ + if (r == SCHEME_MULTIPLE_VALUES) { + Scheme_Thread *p = scheme_current_thread; + if (p->ku.multiple.count == 2) { + if (SCHEME_TRUEP(p->ku.multiple.array[0])) + scheme_cancel_sleep(); + } + } } }