evt:struct with unsafe-poller: skip sleep if poll reports ready

Intended to fix racket/gui#80
This commit is contained in:
Matthew Flatt 2017-10-23 05:57:03 -07:00
parent 81d51789ad
commit ae4e85a6a7
2 changed files with 15 additions and 5 deletions

View File

@ -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.}

View File

@ -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();
}
}
}
}