mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
Make tasks inherit their callers priority (#46179)
Additionally this extracts more functionality into the RunnableVariant which is renamed to GpuiRunnable. Release Notes: - N/A --------- Co-authored-by: Lukas Wirth <lukas@zed.dev> Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
parent
c56b2253b4
commit
1ac2b977fa
15 changed files with 210 additions and 368 deletions
|
|
@ -80,6 +80,7 @@ use workspace::{
|
|||
dock::{DockPosition, Panel, PanelEvent},
|
||||
notifications::{DetachAndPromptErr, ErrorMessagePrompt, NotificationId, NotifyResultExt},
|
||||
};
|
||||
use ztracing::instrument;
|
||||
actions!(
|
||||
git_panel,
|
||||
[
|
||||
|
|
@ -1197,6 +1198,7 @@ impl GitPanel {
|
|||
self.selected_entry.and_then(|i| self.entries.get(i))
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
fn open_diff(&mut self, _: &menu::Confirm, window: &mut Window, cx: &mut Context<Self>) {
|
||||
maybe!({
|
||||
let entry = self.entries.get(self.selected_entry?)?.status_entry()?;
|
||||
|
|
@ -1247,6 +1249,7 @@ impl GitPanel {
|
|||
});
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
fn open_file(
|
||||
&mut self,
|
||||
_: &menu::SecondaryConfirm,
|
||||
|
|
@ -5082,9 +5085,9 @@ impl GitPanel {
|
|||
this.selected_entry = Some(ix);
|
||||
cx.notify();
|
||||
if event.modifiers().secondary() {
|
||||
this.open_file(&Default::default(), window, cx)
|
||||
this.open_file(&Default::default(), window, cx) // here?
|
||||
} else {
|
||||
this.open_diff(&Default::default(), window, cx);
|
||||
this.open_diff(&Default::default(), window, cx); // here?
|
||||
this.focus_handle.focus(window, cx);
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use crate::{App, PlatformDispatcher, RunnableMeta, RunnableVariant, TaskTiming, profiler};
|
||||
use crate::{App, GpuiRunnable, PlatformDispatcher, RunnableMeta, TaskTiming, profiler};
|
||||
use async_task::Runnable;
|
||||
use futures::channel::mpsc;
|
||||
use parking_lot::{Condvar, Mutex};
|
||||
use smol::prelude::*;
|
||||
use std::{
|
||||
cell::Cell,
|
||||
fmt::Debug,
|
||||
marker::PhantomData,
|
||||
mem::{self, ManuallyDrop},
|
||||
|
|
@ -81,7 +82,21 @@ pub enum Priority {
|
|||
Low,
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static CURRENT_TASKS_PRIORITY: Cell<Priority> = const { Cell::new(Priority::Medium) }; }
|
||||
|
||||
impl Priority {
|
||||
/// Sets the priority any spawn call from the runnable about
|
||||
/// to be run will use
|
||||
pub(crate) fn set_as_default_for_spawns(&self) {
|
||||
CURRENT_TASKS_PRIORITY.set(*self);
|
||||
}
|
||||
|
||||
/// Returns the priority from the currently running task
|
||||
pub fn inherit() -> Self {
|
||||
CURRENT_TASKS_PRIORITY.get()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) const fn probability(&self) -> u32 {
|
||||
match self {
|
||||
|
|
@ -329,19 +344,14 @@ impl BackgroundExecutor {
|
|||
.metadata(RunnableMeta {
|
||||
location,
|
||||
app: None,
|
||||
priority: Priority::inherit(),
|
||||
})
|
||||
.spawn_unchecked(
|
||||
move |_| async {
|
||||
let _notify_guard = NotifyOnDrop(pair);
|
||||
future.await
|
||||
},
|
||||
move |runnable| {
|
||||
dispatcher.dispatch(
|
||||
RunnableVariant::Meta(runnable),
|
||||
None,
|
||||
Priority::default(),
|
||||
)
|
||||
},
|
||||
move |runnable| dispatcher.dispatch(GpuiRunnable::GpuiSpawned(runnable), None),
|
||||
)
|
||||
};
|
||||
runnable.schedule();
|
||||
|
|
@ -387,6 +397,7 @@ impl BackgroundExecutor {
|
|||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
Priority::Realtime(realtime).set_as_default_for_spawns();
|
||||
runnable.run();
|
||||
|
||||
let end = Instant::now();
|
||||
|
|
@ -399,6 +410,7 @@ impl BackgroundExecutor {
|
|||
async_task::Builder::new()
|
||||
.metadata(RunnableMeta {
|
||||
location,
|
||||
priority,
|
||||
app: None,
|
||||
})
|
||||
.spawn(
|
||||
|
|
@ -412,13 +424,12 @@ impl BackgroundExecutor {
|
|||
async_task::Builder::new()
|
||||
.metadata(RunnableMeta {
|
||||
location,
|
||||
priority,
|
||||
app: None,
|
||||
})
|
||||
.spawn(
|
||||
move |_| future,
|
||||
move |runnable| {
|
||||
dispatcher.dispatch(RunnableVariant::Meta(runnable), label, priority)
|
||||
},
|
||||
move |runnable| dispatcher.dispatch(GpuiRunnable::GpuiSpawned(runnable), label),
|
||||
)
|
||||
};
|
||||
|
||||
|
|
@ -674,11 +685,14 @@ impl BackgroundExecutor {
|
|||
let (runnable, task) = async_task::Builder::new()
|
||||
.metadata(RunnableMeta {
|
||||
location,
|
||||
priority: Priority::inherit(),
|
||||
app: None,
|
||||
})
|
||||
.spawn(move |_| async move {}, {
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
move |runnable| dispatcher.dispatch_after(duration, RunnableVariant::Meta(runnable))
|
||||
move |runnable| {
|
||||
dispatcher.dispatch_after(duration, GpuiRunnable::GpuiSpawned(runnable))
|
||||
}
|
||||
});
|
||||
runnable.schedule();
|
||||
Task(TaskState::Spawned(task))
|
||||
|
|
@ -785,7 +799,10 @@ impl ForegroundExecutor {
|
|||
}
|
||||
}
|
||||
|
||||
/// Enqueues the given Task to run on the main thread at some point in the future.
|
||||
/// Enqueues the given Task to run on the main thread at some point in the
|
||||
/// future. This inherits the priority of the caller. Use
|
||||
/// [`spawn_with_priority`](Self::spawn_with_priority) if you want to
|
||||
/// overwrite that.
|
||||
#[track_caller]
|
||||
pub fn spawn<R>(&self, future: impl Future<Output = R> + 'static) -> Task<R>
|
||||
where
|
||||
|
|
@ -831,10 +848,11 @@ impl ForegroundExecutor {
|
|||
let (runnable, task) = spawn_local_with_source_location(
|
||||
future,
|
||||
move |runnable| {
|
||||
dispatcher.dispatch_on_main_thread(RunnableVariant::Meta(runnable), priority)
|
||||
dispatcher.dispatch_on_main_thread(GpuiRunnable::GpuiSpawned(runnable))
|
||||
},
|
||||
RunnableMeta {
|
||||
location,
|
||||
priority,
|
||||
app: Some(app),
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -590,7 +590,8 @@ pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle {
|
|||
/// be considered part of our public API.
|
||||
#[doc(hidden)]
|
||||
pub struct RunnableMeta {
|
||||
/// Location of the runnable
|
||||
pub priority: Priority,
|
||||
/// Location of the runnable, only set for futures we spawn
|
||||
pub location: &'static core::panic::Location<'static>,
|
||||
/// Weak reference to check if the app is still alive before running this task
|
||||
pub app: Option<std::sync::Weak<()>>,
|
||||
|
|
@ -599,6 +600,7 @@ pub struct RunnableMeta {
|
|||
impl std::fmt::Debug for RunnableMeta {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("RunnableMeta")
|
||||
.field("priority", &self.priority)
|
||||
.field("location", &self.location)
|
||||
.field("app_alive", &self.is_app_alive())
|
||||
.finish()
|
||||
|
|
@ -615,10 +617,69 @@ impl RunnableMeta {
|
|||
}
|
||||
}
|
||||
|
||||
/// Both of these need meta for priority
|
||||
#[doc(hidden)]
|
||||
pub enum RunnableVariant {
|
||||
Meta(Runnable<RunnableMeta>),
|
||||
Compat(Runnable),
|
||||
pub enum GpuiRunnable {
|
||||
/// Spawned by us, we set useful metadata for profiling and scheduling.
|
||||
/// Yay we have nice things!
|
||||
GpuiSpawned(Runnable<RunnableMeta>),
|
||||
/// Spawned by a dependency through runtimelib. We only have the
|
||||
/// runnable ('task'). No access to metadata.
|
||||
DependencySpawned(Runnable<()>),
|
||||
}
|
||||
|
||||
impl GpuiRunnable {
|
||||
fn run_and_profile(self) -> Instant {
|
||||
if self.app_dropped() {
|
||||
// optimizer will cut it out if it doesnt it does not really matter
|
||||
// cause we are closing the app anyway.
|
||||
return Instant::now();
|
||||
}
|
||||
|
||||
let mut timing = TaskTiming {
|
||||
// use a placeholder location if we dont have one
|
||||
location: self.location().unwrap_or(core::panic::Location::caller()),
|
||||
start: Instant::now(),
|
||||
end: None,
|
||||
};
|
||||
|
||||
crate::profiler::add_task_timing(timing);
|
||||
self.run_unprofiled(); // surrounded by profiling so its ok
|
||||
timing.end = Some(Instant::now());
|
||||
crate::profiler::add_task_timing(timing);
|
||||
timing.start
|
||||
}
|
||||
|
||||
fn app_dropped(&self) -> bool {
|
||||
match self {
|
||||
GpuiRunnable::GpuiSpawned(runnable) => !runnable.metadata().is_app_alive(),
|
||||
GpuiRunnable::DependencySpawned(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn location(&self) -> Option<&'static core::panic::Location<'static>> {
|
||||
match self {
|
||||
GpuiRunnable::GpuiSpawned(runnable) => runnable.metadata().location.into(),
|
||||
GpuiRunnable::DependencySpawned(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// ONLY use for tests or headless client.
|
||||
/// ideally everything should be profiled
|
||||
fn run_unprofiled(self) {
|
||||
self.priority().set_as_default_for_spawns();
|
||||
match self {
|
||||
GpuiRunnable::GpuiSpawned(r) => r.run(),
|
||||
GpuiRunnable::DependencySpawned(r) => r.run(),
|
||||
};
|
||||
}
|
||||
|
||||
fn priority(&self) -> Priority {
|
||||
match self {
|
||||
GpuiRunnable::GpuiSpawned(r) => r.metadata().priority,
|
||||
GpuiRunnable::DependencySpawned(_) => Priority::Medium,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This type is public so that our test macro can generate and use it, but it should not
|
||||
|
|
@ -628,9 +689,9 @@ pub trait PlatformDispatcher: Send + Sync {
|
|||
fn get_all_timings(&self) -> Vec<ThreadTaskTimings>;
|
||||
fn get_current_thread_timings(&self) -> Vec<TaskTiming>;
|
||||
fn is_main_thread(&self) -> bool;
|
||||
fn dispatch(&self, runnable: RunnableVariant, label: Option<TaskLabel>, priority: Priority);
|
||||
fn dispatch_on_main_thread(&self, runnable: RunnableVariant, priority: Priority);
|
||||
fn dispatch_after(&self, duration: Duration, runnable: RunnableVariant);
|
||||
fn dispatch(&self, runnable: GpuiRunnable, label: Option<TaskLabel>);
|
||||
fn dispatch_on_main_thread(&self, runnable: GpuiRunnable);
|
||||
fn dispatch_after(&self, duration: Duration, runnable: GpuiRunnable);
|
||||
fn spawn_realtime(&self, priority: RealtimePriority, f: Box<dyn FnOnce() + Send>);
|
||||
|
||||
fn now(&self) -> Instant {
|
||||
|
|
|
|||
|
|
@ -5,27 +5,22 @@ use calloop::{
|
|||
};
|
||||
use util::ResultExt;
|
||||
|
||||
use std::{
|
||||
mem::MaybeUninit,
|
||||
thread,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use std::{mem::MaybeUninit, thread, time::Duration};
|
||||
|
||||
use crate::{
|
||||
GLOBAL_THREAD_TIMINGS, PlatformDispatcher, Priority, PriorityQueueReceiver,
|
||||
PriorityQueueSender, RealtimePriority, RunnableVariant, THREAD_TIMINGS, TaskLabel, TaskTiming,
|
||||
ThreadTaskTimings, profiler,
|
||||
GLOBAL_THREAD_TIMINGS, GpuiRunnable, PlatformDispatcher, Priority, PriorityQueueReceiver,
|
||||
PriorityQueueSender, RealtimePriority, THREAD_TIMINGS, TaskLabel, ThreadTaskTimings,
|
||||
};
|
||||
|
||||
struct TimerAfter {
|
||||
duration: Duration,
|
||||
runnable: RunnableVariant,
|
||||
runnable: GpuiRunnable,
|
||||
}
|
||||
|
||||
pub(crate) struct LinuxDispatcher {
|
||||
main_sender: PriorityQueueCalloopSender<RunnableVariant>,
|
||||
main_sender: PriorityQueueCalloopSender<GpuiRunnable>,
|
||||
timer_sender: Sender<TimerAfter>,
|
||||
background_sender: PriorityQueueSender<RunnableVariant>,
|
||||
background_sender: PriorityQueueSender<GpuiRunnable>,
|
||||
_background_threads: Vec<thread::JoinHandle<()>>,
|
||||
main_thread_id: thread::ThreadId,
|
||||
}
|
||||
|
|
@ -33,7 +28,7 @@ pub(crate) struct LinuxDispatcher {
|
|||
const MIN_THREADS: usize = 2;
|
||||
|
||||
impl LinuxDispatcher {
|
||||
pub fn new(main_sender: PriorityQueueCalloopSender<RunnableVariant>) -> Self {
|
||||
pub fn new(main_sender: PriorityQueueCalloopSender<GpuiRunnable>) -> Self {
|
||||
let (background_sender, background_receiver) = PriorityQueueReceiver::new();
|
||||
let thread_count =
|
||||
std::thread::available_parallelism().map_or(MIN_THREADS, |i| i.get().max(MIN_THREADS));
|
||||
|
|
@ -42,48 +37,16 @@ impl LinuxDispatcher {
|
|||
// executor
|
||||
let mut background_threads = (0..thread_count)
|
||||
.map(|i| {
|
||||
let mut receiver = background_receiver.clone();
|
||||
let mut receiver: PriorityQueueReceiver<GpuiRunnable> = background_receiver.clone();
|
||||
std::thread::Builder::new()
|
||||
.name(format!("Worker-{i}"))
|
||||
.spawn(move || {
|
||||
for runnable in receiver.iter() {
|
||||
let start = Instant::now();
|
||||
|
||||
let mut location = match runnable {
|
||||
RunnableVariant::Meta(runnable) => {
|
||||
let location = runnable.metadata().location;
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
timing
|
||||
}
|
||||
RunnableVariant::Compat(runnable) => {
|
||||
let location = core::panic::Location::caller();
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
timing
|
||||
}
|
||||
};
|
||||
|
||||
let end = Instant::now();
|
||||
location.end = Some(end);
|
||||
profiler::add_task_timing(location);
|
||||
|
||||
let started = runnable.run_and_profile();
|
||||
log::trace!(
|
||||
"background thread {}: ran runnable. took: {:?}",
|
||||
i,
|
||||
start.elapsed()
|
||||
started.elapsed()
|
||||
);
|
||||
}
|
||||
})
|
||||
|
|
@ -110,36 +73,7 @@ impl LinuxDispatcher {
|
|||
calloop::timer::Timer::from_duration(timer.duration),
|
||||
move |_, _, _| {
|
||||
if let Some(runnable) = runnable.take() {
|
||||
let start = Instant::now();
|
||||
let mut timing = match runnable {
|
||||
RunnableVariant::Meta(runnable) => {
|
||||
let location = runnable.metadata().location;
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
timing
|
||||
}
|
||||
RunnableVariant::Compat(runnable) => {
|
||||
let timing = TaskTiming {
|
||||
location: core::panic::Location::caller(),
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
timing
|
||||
}
|
||||
};
|
||||
let end = Instant::now();
|
||||
|
||||
timing.end = Some(end);
|
||||
profiler::add_task_timing(timing);
|
||||
runnable.run_and_profile();
|
||||
}
|
||||
TimeoutAction::Drop
|
||||
},
|
||||
|
|
@ -189,15 +123,15 @@ impl PlatformDispatcher for LinuxDispatcher {
|
|||
thread::current().id() == self.main_thread_id
|
||||
}
|
||||
|
||||
fn dispatch(&self, runnable: RunnableVariant, _: Option<TaskLabel>, priority: Priority) {
|
||||
fn dispatch(&self, runnable: GpuiRunnable, _: Option<TaskLabel>) {
|
||||
self.background_sender
|
||||
.send(priority, runnable)
|
||||
.send(runnable.priority(), runnable)
|
||||
.unwrap_or_else(|_| panic!("blocking sender returned without value"));
|
||||
}
|
||||
|
||||
fn dispatch_on_main_thread(&self, runnable: RunnableVariant, priority: Priority) {
|
||||
fn dispatch_on_main_thread(&self, runnable: GpuiRunnable) {
|
||||
self.main_sender
|
||||
.send(priority, runnable)
|
||||
.send(runnable.priority(), runnable)
|
||||
.unwrap_or_else(|runnable| {
|
||||
// NOTE: Runnable may wrap a Future that is !Send.
|
||||
//
|
||||
|
|
@ -211,7 +145,7 @@ impl PlatformDispatcher for LinuxDispatcher {
|
|||
});
|
||||
}
|
||||
|
||||
fn dispatch_after(&self, duration: Duration, runnable: RunnableVariant) {
|
||||
fn dispatch_after(&self, duration: Duration, runnable: GpuiRunnable) {
|
||||
self.timer_sender
|
||||
.send(TimerAfter { duration, runnable })
|
||||
.ok();
|
||||
|
|
|
|||
|
|
@ -31,10 +31,7 @@ impl HeadlessClient {
|
|||
handle
|
||||
.insert_source(main_receiver, |event, _, _: &mut HeadlessClient| {
|
||||
if let calloop::channel::Event::Msg(runnable) = event {
|
||||
match runnable {
|
||||
crate::RunnableVariant::Meta(runnable) => runnable.run(),
|
||||
crate::RunnableVariant::Compat(runnable) => runnable.run(),
|
||||
};
|
||||
runnable.run_unprofiled();
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ use xkbcommon::xkb::{self, Keycode, Keysym, State};
|
|||
|
||||
use crate::{
|
||||
Action, AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId,
|
||||
ForegroundExecutor, Keymap, LinuxDispatcher, Menu, MenuItem, OwnedMenu, PathPromptOptions,
|
||||
Pixels, Platform, PlatformDisplay, PlatformKeyboardLayout, PlatformKeyboardMapper,
|
||||
PlatformTextSystem, PlatformWindow, Point, PriorityQueueCalloopReceiver, Result,
|
||||
RunnableVariant, Task, WindowAppearance, WindowParams, px,
|
||||
ForegroundExecutor, GpuiRunnable, Keymap, LinuxDispatcher, Menu, MenuItem, OwnedMenu,
|
||||
PathPromptOptions, Pixels, Platform, PlatformDisplay, PlatformKeyboardLayout,
|
||||
PlatformKeyboardMapper, PlatformTextSystem, PlatformWindow, Point,
|
||||
PriorityQueueCalloopReceiver, Result, Task, WindowAppearance, WindowParams, px,
|
||||
};
|
||||
|
||||
#[cfg(any(feature = "wayland", feature = "x11"))]
|
||||
|
|
@ -152,7 +152,7 @@ impl LinuxCommon {
|
|||
pub fn new(
|
||||
signal: LoopSignal,
|
||||
liveness: std::sync::Weak<()>,
|
||||
) -> (Self, PriorityQueueCalloopReceiver<RunnableVariant>) {
|
||||
) -> (Self, PriorityQueueCalloopReceiver<GpuiRunnable>) {
|
||||
let (main_sender, main_receiver) = PriorityQueueCalloopReceiver::new();
|
||||
|
||||
#[cfg(any(feature = "wayland", feature = "x11"))]
|
||||
|
|
|
|||
|
|
@ -73,17 +73,14 @@ use super::{
|
|||
window::{ImeInput, WaylandWindowStatePtr},
|
||||
};
|
||||
|
||||
use crate::platform::{PlatformWindow, blade::BladeContext};
|
||||
use crate::{
|
||||
AnyWindowHandle, Bounds, Capslock, CursorStyle, DOUBLE_CLICK_INTERVAL, DevicePixels, DisplayId,
|
||||
FileDropEvent, ForegroundExecutor, KeyDownEvent, KeyUpEvent, Keystroke, LinuxCommon,
|
||||
LinuxKeyboardLayout, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent,
|
||||
MouseExitEvent, MouseMoveEvent, MouseUpEvent, NavigationDirection, Pixels, PlatformDisplay,
|
||||
PlatformInput, PlatformKeyboardLayout, Point, ResultExt as _, SCROLL_LINES, ScrollDelta,
|
||||
ScrollWheelEvent, Size, TouchPhase, WindowParams, point, profiler, px, size,
|
||||
};
|
||||
use crate::{
|
||||
RunnableVariant, TaskTiming,
|
||||
platform::{PlatformWindow, blade::BladeContext},
|
||||
ScrollWheelEvent, Size, TouchPhase, WindowParams, point, px, size,
|
||||
};
|
||||
use crate::{
|
||||
SharedString,
|
||||
|
|
@ -498,38 +495,8 @@ impl WaylandClient {
|
|||
let handle = handle.clone();
|
||||
move |event, _, _: &mut WaylandClientStatePtr| {
|
||||
if let calloop::channel::Event::Msg(runnable) = event {
|
||||
handle.insert_idle(|_| {
|
||||
let start = Instant::now();
|
||||
let mut timing = match runnable {
|
||||
RunnableVariant::Meta(runnable) => {
|
||||
let location = runnable.metadata().location;
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
timing
|
||||
}
|
||||
RunnableVariant::Compat(runnable) => {
|
||||
let location = core::panic::Location::caller();
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
timing
|
||||
}
|
||||
};
|
||||
|
||||
let end = Instant::now();
|
||||
timing.end = Some(end);
|
||||
profiler::add_task_timing(timing);
|
||||
handle.insert_idle(move |_| {
|
||||
runnable.run_and_profile();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Capslock, ResultExt as _, RunnableVariant, TaskTiming, profiler, xcb_flush};
|
||||
use crate::{Capslock, ResultExt as _, xcb_flush};
|
||||
use anyhow::{Context as _, anyhow};
|
||||
use ashpd::WindowIdentifier;
|
||||
use calloop::{
|
||||
|
|
@ -313,37 +313,7 @@ impl X11Client {
|
|||
// events have higher priority and runnables are only worked off after the event
|
||||
// callbacks.
|
||||
handle.insert_idle(|_| {
|
||||
let start = Instant::now();
|
||||
let mut timing = match runnable {
|
||||
RunnableVariant::Meta(runnable) => {
|
||||
let location = runnable.metadata().location;
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
timing
|
||||
}
|
||||
RunnableVariant::Compat(runnable) => {
|
||||
let location = core::panic::Location::caller();
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
timing
|
||||
}
|
||||
};
|
||||
|
||||
let end = Instant::now();
|
||||
timing.end = Some(end);
|
||||
profiler::add_task_timing(timing);
|
||||
runnable.run_and_profile();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use crate::{
|
||||
GLOBAL_THREAD_TIMINGS, PlatformDispatcher, Priority, RealtimePriority, RunnableMeta,
|
||||
RunnableVariant, THREAD_TIMINGS, TaskLabel, TaskTiming, ThreadTaskTimings,
|
||||
GLOBAL_THREAD_TIMINGS, GpuiRunnable, PlatformDispatcher, Priority, RealtimePriority,
|
||||
RunnableMeta, THREAD_TIMINGS, TaskLabel, TaskTiming, ThreadTaskTimings,
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
|
|
@ -28,7 +28,7 @@ use std::{
|
|||
ffi::c_void,
|
||||
mem::MaybeUninit,
|
||||
ptr::{NonNull, addr_of},
|
||||
time::{Duration, Instant},
|
||||
time::Duration,
|
||||
};
|
||||
use util::ResultExt;
|
||||
|
||||
|
|
@ -69,25 +69,25 @@ impl PlatformDispatcher for MacDispatcher {
|
|||
is_main_thread == YES
|
||||
}
|
||||
|
||||
fn dispatch(&self, runnable: RunnableVariant, _: Option<TaskLabel>, priority: Priority) {
|
||||
let (context, trampoline) = match runnable {
|
||||
RunnableVariant::Meta(runnable) => (
|
||||
runnable.into_raw().as_ptr() as *mut c_void,
|
||||
Some(trampoline as unsafe extern "C" fn(*mut c_void)),
|
||||
),
|
||||
RunnableVariant::Compat(runnable) => (
|
||||
runnable.into_raw().as_ptr() as *mut c_void,
|
||||
Some(trampoline_compat as unsafe extern "C" fn(*mut c_void)),
|
||||
),
|
||||
};
|
||||
|
||||
let queue_priority = match priority {
|
||||
fn dispatch(&self, runnable: GpuiRunnable, _: Option<TaskLabel>) {
|
||||
let queue_priority = match runnable.priority() {
|
||||
Priority::Realtime(_) => unreachable!(),
|
||||
Priority::High => DISPATCH_QUEUE_PRIORITY_HIGH as isize,
|
||||
Priority::Medium => DISPATCH_QUEUE_PRIORITY_DEFAULT as isize,
|
||||
Priority::Low => DISPATCH_QUEUE_PRIORITY_LOW as isize,
|
||||
};
|
||||
|
||||
let (context, trampoline) = match runnable {
|
||||
GpuiRunnable::GpuiSpawned(runnable) => (
|
||||
runnable.into_raw().as_ptr() as *mut c_void,
|
||||
Some(trampoline as unsafe extern "C" fn(*mut c_void)),
|
||||
),
|
||||
GpuiRunnable::DependencySpawned(runnable) => (
|
||||
runnable.into_raw().as_ptr() as *mut c_void,
|
||||
Some(trampoline_compat as unsafe extern "C" fn(*mut c_void)),
|
||||
),
|
||||
};
|
||||
|
||||
unsafe {
|
||||
dispatch_async_f(
|
||||
dispatch_get_global_queue(queue_priority, 0),
|
||||
|
|
@ -97,13 +97,13 @@ impl PlatformDispatcher for MacDispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
fn dispatch_on_main_thread(&self, runnable: RunnableVariant, _priority: Priority) {
|
||||
fn dispatch_on_main_thread(&self, runnable: GpuiRunnable) {
|
||||
let (context, trampoline) = match runnable {
|
||||
RunnableVariant::Meta(runnable) => (
|
||||
GpuiRunnable::GpuiSpawned(runnable) => (
|
||||
runnable.into_raw().as_ptr() as *mut c_void,
|
||||
Some(trampoline as unsafe extern "C" fn(*mut c_void)),
|
||||
),
|
||||
RunnableVariant::Compat(runnable) => (
|
||||
GpuiRunnable::DependencySpawned(runnable) => (
|
||||
runnable.into_raw().as_ptr() as *mut c_void,
|
||||
Some(trampoline_compat as unsafe extern "C" fn(*mut c_void)),
|
||||
),
|
||||
|
|
@ -113,13 +113,13 @@ impl PlatformDispatcher for MacDispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
fn dispatch_after(&self, duration: Duration, runnable: RunnableVariant) {
|
||||
fn dispatch_after(&self, duration: Duration, runnable: GpuiRunnable) {
|
||||
let (context, trampoline) = match runnable {
|
||||
RunnableVariant::Meta(runnable) => (
|
||||
GpuiRunnable::GpuiSpawned(runnable) => (
|
||||
runnable.into_raw().as_ptr() as *mut c_void,
|
||||
Some(trampoline as unsafe extern "C" fn(*mut c_void)),
|
||||
),
|
||||
RunnableVariant::Compat(runnable) => (
|
||||
GpuiRunnable::DependencySpawned(runnable) => (
|
||||
runnable.into_raw().as_ptr() as *mut c_void,
|
||||
Some(trampoline_compat as unsafe extern "C" fn(*mut c_void)),
|
||||
),
|
||||
|
|
@ -247,82 +247,19 @@ fn set_audio_thread_priority() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// Note we can not send through a GpuiRunnable as that would require allocating
|
||||
// to keep the pointer alive. So we recreate it here.
|
||||
extern "C" fn trampoline(runnable: *mut c_void) {
|
||||
let task =
|
||||
unsafe { Runnable::<RunnableMeta>::from_raw(NonNull::new_unchecked(runnable as *mut ())) };
|
||||
|
||||
let metadata = task.metadata();
|
||||
let location = metadata.location;
|
||||
|
||||
if !metadata.is_app_alive() {
|
||||
drop(task);
|
||||
return;
|
||||
}
|
||||
|
||||
let start = Instant::now();
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
|
||||
THREAD_TIMINGS.with(|timings| {
|
||||
let mut timings = timings.lock();
|
||||
let timings = &mut timings.timings;
|
||||
if let Some(last_timing) = timings.iter_mut().rev().next() {
|
||||
if last_timing.location == timing.location {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
timings.push_back(timing);
|
||||
});
|
||||
|
||||
task.run();
|
||||
let end = Instant::now();
|
||||
|
||||
THREAD_TIMINGS.with(|timings| {
|
||||
let mut timings = timings.lock();
|
||||
let timings = &mut timings.timings;
|
||||
let Some(last_timing) = timings.iter_mut().rev().next() else {
|
||||
return;
|
||||
};
|
||||
last_timing.end = Some(end);
|
||||
});
|
||||
let task = GpuiRunnable::GpuiSpawned(task);
|
||||
task.run_and_profile();
|
||||
}
|
||||
|
||||
// Note we can not send through a GpuiRunnable as that would require allocating
|
||||
// to keep the pointer alive. So we recreate it here.
|
||||
extern "C" fn trampoline_compat(runnable: *mut c_void) {
|
||||
let task = unsafe { Runnable::<()>::from_raw(NonNull::new_unchecked(runnable as *mut ())) };
|
||||
|
||||
let location = core::panic::Location::caller();
|
||||
|
||||
let start = Instant::now();
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
THREAD_TIMINGS.with(|timings| {
|
||||
let mut timings = timings.lock();
|
||||
let timings = &mut timings.timings;
|
||||
if let Some(last_timing) = timings.iter_mut().rev().next() {
|
||||
if last_timing.location == timing.location {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
timings.push_back(timing);
|
||||
});
|
||||
|
||||
task.run();
|
||||
let end = Instant::now();
|
||||
|
||||
THREAD_TIMINGS.with(|timings| {
|
||||
let mut timings = timings.lock();
|
||||
let timings = &mut timings.timings;
|
||||
let Some(last_timing) = timings.iter_mut().rev().next() else {
|
||||
return;
|
||||
};
|
||||
last_timing.end = Some(end);
|
||||
});
|
||||
let task = GpuiRunnable::DependencySpawned(task);
|
||||
task.run_and_profile();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{PlatformDispatcher, Priority, RunnableVariant, TaskLabel};
|
||||
use crate::{GpuiRunnable, PlatformDispatcher, TaskLabel};
|
||||
use backtrace::Backtrace;
|
||||
use collections::{HashMap, HashSet, VecDeque};
|
||||
use parking::Unparker;
|
||||
|
|
@ -25,10 +25,10 @@ pub struct TestDispatcher {
|
|||
|
||||
struct TestDispatcherState {
|
||||
random: StdRng,
|
||||
foreground: HashMap<TestDispatcherId, VecDeque<RunnableVariant>>,
|
||||
background: Vec<RunnableVariant>,
|
||||
deprioritized_background: Vec<RunnableVariant>,
|
||||
delayed: Vec<(Duration, RunnableVariant)>,
|
||||
foreground: HashMap<TestDispatcherId, VecDeque<GpuiRunnable>>,
|
||||
background: Vec<GpuiRunnable>,
|
||||
deprioritized_background: Vec<GpuiRunnable>,
|
||||
delayed: Vec<(Duration, GpuiRunnable)>,
|
||||
start_time: Instant,
|
||||
time: Duration,
|
||||
is_main_thread: bool,
|
||||
|
|
@ -176,21 +176,10 @@ impl TestDispatcher {
|
|||
drop(state);
|
||||
|
||||
// todo(localcc): add timings to tests
|
||||
match runnable {
|
||||
RunnableVariant::Meta(runnable) => {
|
||||
if !runnable.metadata().is_app_alive() {
|
||||
drop(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
RunnableVariant::Compat(runnable) => {
|
||||
runnable.run();
|
||||
}
|
||||
};
|
||||
|
||||
if !runnable.app_dropped() {
|
||||
runnable.run_unprofiled()
|
||||
}
|
||||
self.state.lock().is_main_thread = was_main_thread;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -292,7 +281,7 @@ impl PlatformDispatcher for TestDispatcher {
|
|||
state.start_time + state.time
|
||||
}
|
||||
|
||||
fn dispatch(&self, runnable: RunnableVariant, label: Option<TaskLabel>, _priority: Priority) {
|
||||
fn dispatch(&self, runnable: GpuiRunnable, label: Option<TaskLabel>) {
|
||||
{
|
||||
let mut state = self.state.lock();
|
||||
if label.is_some_and(|label| state.deprioritized_task_labels.contains(&label)) {
|
||||
|
|
@ -304,7 +293,7 @@ impl PlatformDispatcher for TestDispatcher {
|
|||
self.unpark_all();
|
||||
}
|
||||
|
||||
fn dispatch_on_main_thread(&self, runnable: RunnableVariant, _priority: Priority) {
|
||||
fn dispatch_on_main_thread(&self, runnable: GpuiRunnable) {
|
||||
self.state
|
||||
.lock()
|
||||
.foreground
|
||||
|
|
@ -314,7 +303,7 @@ impl PlatformDispatcher for TestDispatcher {
|
|||
self.unpark_all();
|
||||
}
|
||||
|
||||
fn dispatch_after(&self, duration: std::time::Duration, runnable: RunnableVariant) {
|
||||
fn dispatch_after(&self, duration: std::time::Duration, runnable: GpuiRunnable) {
|
||||
let mut state = self.state.lock();
|
||||
let next_time = state.time + duration;
|
||||
let ix = match state.delayed.binary_search_by_key(&next_time, |e| e.0) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
thread::{ThreadId, current},
|
||||
time::{Duration, Instant},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
|
|
@ -21,14 +21,14 @@ use windows::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
GLOBAL_THREAD_TIMINGS, HWND, PlatformDispatcher, Priority, PriorityQueueSender,
|
||||
RealtimePriority, RunnableVariant, SafeHwnd, THREAD_TIMINGS, TaskLabel, TaskTiming,
|
||||
ThreadTaskTimings, WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD, profiler,
|
||||
GLOBAL_THREAD_TIMINGS, GpuiRunnable, HWND, PlatformDispatcher, Priority, PriorityQueueSender,
|
||||
RealtimePriority, SafeHwnd, THREAD_TIMINGS, TaskLabel, ThreadTaskTimings,
|
||||
WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD,
|
||||
};
|
||||
|
||||
pub(crate) struct WindowsDispatcher {
|
||||
pub(crate) wake_posted: AtomicBool,
|
||||
main_sender: PriorityQueueSender<RunnableVariant>,
|
||||
main_sender: PriorityQueueSender<GpuiRunnable>,
|
||||
main_thread_id: ThreadId,
|
||||
pub(crate) platform_window_handle: SafeHwnd,
|
||||
validation_number: usize,
|
||||
|
|
@ -36,7 +36,7 @@ pub(crate) struct WindowsDispatcher {
|
|||
|
||||
impl WindowsDispatcher {
|
||||
pub(crate) fn new(
|
||||
main_sender: PriorityQueueSender<RunnableVariant>,
|
||||
main_sender: PriorityQueueSender<GpuiRunnable>,
|
||||
platform_window_handle: HWND,
|
||||
validation_number: usize,
|
||||
) -> Self {
|
||||
|
|
@ -52,11 +52,14 @@ impl WindowsDispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
fn dispatch_on_threadpool(&self, priority: WorkItemPriority, runnable: RunnableVariant) {
|
||||
fn dispatch_on_threadpool(&self, runnable: GpuiRunnable, priority: WorkItemPriority) {
|
||||
let handler = {
|
||||
let mut task_wrapper = Some(runnable);
|
||||
let mut runnable = Some(runnable);
|
||||
WorkItemHandler::new(move |_| {
|
||||
Self::execute_runnable(task_wrapper.take().unwrap());
|
||||
runnable
|
||||
.take()
|
||||
.expect("Takes FnMut but only runs once")
|
||||
.run_and_profile();
|
||||
Ok(())
|
||||
})
|
||||
};
|
||||
|
|
@ -64,54 +67,19 @@ impl WindowsDispatcher {
|
|||
ThreadPool::RunWithPriorityAsync(&handler, priority).log_err();
|
||||
}
|
||||
|
||||
fn dispatch_on_threadpool_after(&self, runnable: RunnableVariant, duration: Duration) {
|
||||
fn dispatch_on_threadpool_after(&self, runnable: GpuiRunnable, duration: Duration) {
|
||||
let handler = {
|
||||
let mut task_wrapper = Some(runnable);
|
||||
let mut runnable = Some(runnable);
|
||||
TimerElapsedHandler::new(move |_| {
|
||||
Self::execute_runnable(task_wrapper.take().unwrap());
|
||||
runnable
|
||||
.take()
|
||||
.expect("Takes FnMut but only runs once")
|
||||
.run_and_profile();
|
||||
Ok(())
|
||||
})
|
||||
};
|
||||
ThreadPoolTimer::CreateTimer(&handler, duration.into()).log_err();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn execute_runnable(runnable: RunnableVariant) {
|
||||
let start = Instant::now();
|
||||
|
||||
let mut timing = match runnable {
|
||||
RunnableVariant::Meta(runnable) => {
|
||||
let location = runnable.metadata().location;
|
||||
let timing = TaskTiming {
|
||||
location,
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
|
||||
timing
|
||||
}
|
||||
RunnableVariant::Compat(runnable) => {
|
||||
let timing = TaskTiming {
|
||||
location: core::panic::Location::caller(),
|
||||
start,
|
||||
end: None,
|
||||
};
|
||||
profiler::add_task_timing(timing);
|
||||
|
||||
runnable.run();
|
||||
|
||||
timing
|
||||
}
|
||||
};
|
||||
|
||||
let end = Instant::now();
|
||||
timing.end = Some(end);
|
||||
|
||||
profiler::add_task_timing(timing);
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformDispatcher for WindowsDispatcher {
|
||||
|
|
@ -138,22 +106,21 @@ impl PlatformDispatcher for WindowsDispatcher {
|
|||
current().id() == self.main_thread_id
|
||||
}
|
||||
|
||||
fn dispatch(&self, runnable: RunnableVariant, label: Option<TaskLabel>, priority: Priority) {
|
||||
let priority = match priority {
|
||||
fn dispatch(&self, runnable: GpuiRunnable, label: Option<TaskLabel>) {
|
||||
let priority = match runnable.priority() {
|
||||
Priority::Realtime(_) => unreachable!(),
|
||||
Priority::High => WorkItemPriority::High,
|
||||
Priority::Medium => WorkItemPriority::Normal,
|
||||
Priority::Low => WorkItemPriority::Low,
|
||||
};
|
||||
self.dispatch_on_threadpool(priority, runnable);
|
||||
|
||||
self.dispatch_on_threadpool(runnable, priority);
|
||||
if let Some(label) = label {
|
||||
log::debug!("TaskLabel: {label:?}");
|
||||
}
|
||||
}
|
||||
|
||||
fn dispatch_on_main_thread(&self, runnable: RunnableVariant, priority: Priority) {
|
||||
match self.main_sender.send(priority, runnable) {
|
||||
fn dispatch_on_main_thread(&self, runnable: GpuiRunnable) {
|
||||
match self.main_sender.send(runnable.priority(), runnable) {
|
||||
Ok(_) => {
|
||||
if !self.wake_posted.swap(true, Ordering::AcqRel) {
|
||||
unsafe {
|
||||
|
|
@ -181,7 +148,7 @@ impl PlatformDispatcher for WindowsDispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
fn dispatch_after(&self, duration: Duration, runnable: RunnableVariant) {
|
||||
fn dispatch_after(&self, duration: Duration, runnable: GpuiRunnable) {
|
||||
self.dispatch_on_threadpool_after(runnable, duration);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ impl WindowsWindowInner {
|
|||
if wparam.0 == SIZE_MOVE_LOOP_TIMER_ID {
|
||||
let mut runnables = self.main_receiver.clone().try_iter();
|
||||
while let Some(Ok(runnable)) = runnables.next() {
|
||||
WindowsDispatcher::execute_runnable(runnable);
|
||||
runnable.run_and_profile();
|
||||
}
|
||||
self.handle_paint_msg(handle)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ struct WindowsPlatformInner {
|
|||
raw_window_handles: std::sync::Weak<RwLock<SmallVec<[SafeHwnd; 4]>>>,
|
||||
// The below members will never change throughout the entire lifecycle of the app.
|
||||
validation_number: usize,
|
||||
main_receiver: PriorityQueueReceiver<RunnableVariant>,
|
||||
main_receiver: PriorityQueueReceiver<GpuiRunnable>,
|
||||
dispatcher: Arc<WindowsDispatcher>,
|
||||
}
|
||||
|
||||
|
|
@ -856,7 +856,7 @@ impl WindowsPlatformInner {
|
|||
}
|
||||
let mut main_receiver = self.main_receiver.clone();
|
||||
match main_receiver.try_pop() {
|
||||
Ok(Some(runnable)) => WindowsDispatcher::execute_runnable(runnable),
|
||||
Ok(Some(runnable)) => _ = runnable.run_and_profile(),
|
||||
_ => break 'timeout_loop,
|
||||
}
|
||||
}
|
||||
|
|
@ -868,8 +868,7 @@ impl WindowsPlatformInner {
|
|||
match main_receiver.try_pop() {
|
||||
Ok(Some(runnable)) => {
|
||||
self.dispatcher.wake_posted.store(true, Ordering::Release);
|
||||
|
||||
WindowsDispatcher::execute_runnable(runnable);
|
||||
runnable.run_and_profile();
|
||||
}
|
||||
_ => break 'tasks,
|
||||
}
|
||||
|
|
@ -933,7 +932,7 @@ pub(crate) struct WindowCreationInfo {
|
|||
pub(crate) windows_version: WindowsVersion,
|
||||
pub(crate) drop_target_helper: IDropTargetHelper,
|
||||
pub(crate) validation_number: usize,
|
||||
pub(crate) main_receiver: PriorityQueueReceiver<RunnableVariant>,
|
||||
pub(crate) main_receiver: PriorityQueueReceiver<GpuiRunnable>,
|
||||
pub(crate) platform_window_handle: HWND,
|
||||
pub(crate) disable_direct_composition: bool,
|
||||
pub(crate) directx_devices: DirectXDevices,
|
||||
|
|
@ -946,8 +945,8 @@ struct PlatformWindowCreateContext {
|
|||
inner: Option<Result<Rc<WindowsPlatformInner>>>,
|
||||
raw_window_handles: std::sync::Weak<RwLock<SmallVec<[SafeHwnd; 4]>>>,
|
||||
validation_number: usize,
|
||||
main_sender: Option<PriorityQueueSender<RunnableVariant>>,
|
||||
main_receiver: Option<PriorityQueueReceiver<RunnableVariant>>,
|
||||
main_sender: Option<PriorityQueueSender<GpuiRunnable>>,
|
||||
main_receiver: Option<PriorityQueueReceiver<GpuiRunnable>>,
|
||||
directx_devices: Option<DirectXDevices>,
|
||||
dispatcher: Option<Arc<WindowsDispatcher>>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ pub(crate) struct WindowsWindowInner {
|
|||
pub(crate) executor: ForegroundExecutor,
|
||||
pub(crate) windows_version: WindowsVersion,
|
||||
pub(crate) validation_number: usize,
|
||||
pub(crate) main_receiver: PriorityQueueReceiver<RunnableVariant>,
|
||||
pub(crate) main_receiver: PriorityQueueReceiver<GpuiRunnable>,
|
||||
pub(crate) platform_window_handle: HWND,
|
||||
pub(crate) parent_hwnd: Option<HWND>,
|
||||
}
|
||||
|
|
@ -366,7 +366,7 @@ struct WindowCreateContext {
|
|||
windows_version: WindowsVersion,
|
||||
drop_target_helper: IDropTargetHelper,
|
||||
validation_number: usize,
|
||||
main_receiver: PriorityQueueReceiver<RunnableVariant>,
|
||||
main_receiver: PriorityQueueReceiver<GpuiRunnable>,
|
||||
platform_window_handle: HWND,
|
||||
appearance: WindowAppearance,
|
||||
disable_direct_composition: bool,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ mod session;
|
|||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use async_dispatcher::{Dispatcher, Runnable, set_dispatcher};
|
||||
use gpui::{App, PlatformDispatcher, Priority, RunnableVariant};
|
||||
use gpui::{App, GpuiRunnable, PlatformDispatcher};
|
||||
use project::Fs;
|
||||
pub use runtimelib::ExecutionState;
|
||||
|
||||
|
|
@ -46,12 +46,12 @@ fn zed_dispatcher(cx: &mut App) -> impl Dispatcher {
|
|||
impl Dispatcher for ZedDispatcher {
|
||||
fn dispatch(&self, runnable: Runnable) {
|
||||
self.dispatcher
|
||||
.dispatch(RunnableVariant::Compat(runnable), None, Priority::default());
|
||||
.dispatch(GpuiRunnable::DependencySpawned(runnable), None);
|
||||
}
|
||||
|
||||
fn dispatch_after(&self, duration: Duration, runnable: Runnable) {
|
||||
self.dispatcher
|
||||
.dispatch_after(duration, RunnableVariant::Compat(runnable));
|
||||
.dispatch_after(duration, GpuiRunnable::DependencySpawned(runnable));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue