logiguard fork v2: patched GPUI on verified 8c74db0 tree
Rebuilt from the exact zed-industries/zed @ 8c74db00c4053d6c0a9037863d7bd048658da4ca tree (previous orphan was based on a stale/wrong fetch). Same 3-file patch: - serial.rs: add SerialKind::KeyboardEnter - client.rs: store wl_keyboard.enter serial; add latest_serial_of() - window.rs: activate() uses keyboard-enter serial (Mutter focus gate) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
mod clock;
|
||||
mod executor;
|
||||
mod test_scheduler;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use clock::*;
|
||||
pub use executor::*;
|
||||
pub use test_scheduler::*;
|
||||
|
||||
use async_task::Runnable;
|
||||
use futures::channel::oneshot;
|
||||
use std::{
|
||||
future::Future,
|
||||
panic::Location,
|
||||
pin::Pin,
|
||||
sync::Arc,
|
||||
task::{Context, Poll},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
/// Task priority for background tasks.
|
||||
///
|
||||
/// Higher priority tasks are more likely to be scheduled before lower priority tasks,
|
||||
/// but this is not a strict guarantee - the scheduler may interleave tasks of different
|
||||
/// priorities to prevent starvation.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
|
||||
#[repr(u8)]
|
||||
pub enum Priority {
|
||||
/// Realtime priority
|
||||
///
|
||||
/// Spawning a task with this priority will spin it off on a separate thread dedicated just to that task. Only use for audio.
|
||||
RealtimeAudio,
|
||||
/// High priority - use for tasks critical to user experience/responsiveness.
|
||||
High,
|
||||
/// Medium priority - suitable for most use cases.
|
||||
#[default]
|
||||
Medium,
|
||||
/// Low priority - use for background work that can be deprioritized.
|
||||
Low,
|
||||
}
|
||||
|
||||
impl Priority {
|
||||
/// Returns the relative probability weight for this priority level.
|
||||
/// Used by schedulers to determine task selection probability.
|
||||
pub const fn weight(self) -> u32 {
|
||||
match self {
|
||||
Priority::High => 60,
|
||||
Priority::Medium => 30,
|
||||
Priority::Low => 10,
|
||||
// realtime priorities are not considered for probability scheduling
|
||||
Priority::RealtimeAudio => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata attached to runnables for debugging and profiling.
|
||||
#[derive(Clone)]
|
||||
pub struct RunnableMeta {
|
||||
/// The source location where the task was spawned.
|
||||
pub location: &'static Location<'static>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for RunnableMeta {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("RunnableMeta")
|
||||
.field("location", &self.location)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Scheduler: Send + Sync {
|
||||
/// Block until the given future completes or timeout occurs.
|
||||
///
|
||||
/// Returns `true` if the future completed, `false` if it timed out.
|
||||
/// The future is passed as a pinned mutable reference so the caller
|
||||
/// retains ownership and can continue polling or return it on timeout.
|
||||
fn block(
|
||||
&self,
|
||||
session_id: Option<SessionId>,
|
||||
future: Pin<&mut dyn Future<Output = ()>>,
|
||||
timeout: Option<Duration>,
|
||||
) -> bool;
|
||||
|
||||
fn schedule_foreground(&self, session_id: SessionId, runnable: Runnable<RunnableMeta>);
|
||||
|
||||
/// Schedule a background task with the given priority.
|
||||
fn schedule_background_with_priority(
|
||||
&self,
|
||||
runnable: Runnable<RunnableMeta>,
|
||||
priority: Priority,
|
||||
);
|
||||
|
||||
/// Spawn a closure on a dedicated realtime thread for audio processing.
|
||||
fn spawn_realtime(&self, f: Box<dyn FnOnce() + Send>);
|
||||
|
||||
/// Schedule a background task with default (medium) priority.
|
||||
fn schedule_background(&self, runnable: Runnable<RunnableMeta>) {
|
||||
self.schedule_background_with_priority(runnable, Priority::default());
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn timer(&self, timeout: Duration) -> Timer;
|
||||
fn clock(&self) -> Arc<dyn Clock>;
|
||||
|
||||
fn as_test(&self) -> Option<&TestScheduler> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub struct SessionId(u16);
|
||||
|
||||
impl SessionId {
|
||||
pub fn new(id: u16) -> Self {
|
||||
SessionId(id)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Timer(oneshot::Receiver<()>);
|
||||
|
||||
impl Timer {
|
||||
pub fn new(rx: oneshot::Receiver<()>) -> Self {
|
||||
Timer(rx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Future for Timer {
|
||||
type Output = ();
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
|
||||
match Pin::new(&mut self.0).poll(cx) {
|
||||
Poll::Ready(_) => Poll::Ready(()),
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user