-
Notifications
You must be signed in to change notification settings - Fork 668
Description
Today the CurrentThread API I think isn’t easily amenable to integration with a foreign event loop, such as the glib event loop in GTK. (a case I've forgotten about until now by accident!). The main gist of the problem is that right now the main way to customize the CurrentThread behavior is via the Sleep trait but that requires that Rust is the one which requests that the current thread block, whereas in a GTK/glib application Rust isn't the one doing that but C is.
I think we may want to add some form of nonblocking "move spawned tasks forward" API like:
pub struct TaskRunner { /* ... */ }
impl TaskRunner {
pub fn new() -> TaskRunner;
// executes a closure where this task runner is the "ambient"
// task runner where tasks are spawned
//
// panics if called recursively
pub fn set_default(&mut self, f: impl FnOnce());
// In a nonblocking fashion pushes all tasks forward
//
// if a task isn't ready then `wakeup` will be notified when it is
//
// panics if called within `set_default` (can't recurse)
pub fn poll(&mut self, wakeup: SomeWakeupHandle);
}With an API like that we could update the existing APIs behaviorally like:
pub struct CurrentThread { /* ... */ }
impl CurrentThread {
// These functions will route to a `TaskRunner` if configured via
// `set_default` or `poll`.
pub fn execute(f: impl Future<Item = (), Error = ()>);
pub fn execute_daemon(f: impl Future<Item = (), Error = ()>);
pub fn cancel_all_executing();
// In addition to the current panic conditions, these functions will
// panic if `poll` or `set_default` above was previously called.
pub fn run<R>(f: impl FnOnce(&mut Context) -> R) -> R;
pub fn run_with_sleep<R>(s: &mut impl Sleep,
f: impl FnOnce(&mut Context) -> R) -> R;
}Effectively we'd just export some of the internals of the current thread module to interact a little more closely with external systems. We'd then require foreign event loop integration to look like:
- When booted they'd create a
TaskRunner - Whenever Rust code is executed they execute
set_defaultto get spawning to work - When ready, the
TaskRunneris polled with the ability to route wakeups to the glib event loop
I think this'd work for glib integration, but curious what others think!