kms: Don't block surface-threads on startup cond

This commit is contained in:
Victoria Brekenfeld 2024-06-11 17:24:46 +02:00 committed by Victoria Brekenfeld
parent 31ff17a323
commit 12fab6e220
6 changed files with 24 additions and 24 deletions

View file

@ -32,7 +32,7 @@ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
fmt, fmt,
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::{Arc, Condvar, Mutex, RwLock}, sync::{atomic::AtomicBool, Arc, RwLock},
}; };
use super::{drm_helpers, socket::Socket, surface::Surface}; use super::{drm_helpers, socket::Socket, surface::Surface};
@ -475,7 +475,7 @@ impl Device {
position: (i32, i32), position: (i32, i32),
evlh: &LoopHandle<'static, State>, evlh: &LoopHandle<'static, State>,
shell: Arc<RwLock<Shell>>, shell: Arc<RwLock<Shell>>,
startup_done: Arc<(Mutex<bool>, Condvar)>, startup_done: Arc<AtomicBool>,
) -> Result<(Output, bool)> { ) -> Result<(Output, bool)> {
let output = self let output = self
.outputs .outputs

View file

@ -35,7 +35,7 @@ use std::{
borrow::BorrowMut, borrow::BorrowMut,
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
path::Path, path::Path,
sync::{Arc, Condvar, Mutex, RwLock}, sync::{atomic::AtomicBool, Arc, RwLock},
}; };
mod device; mod device;
@ -474,7 +474,7 @@ impl KmsState {
test_only: bool, test_only: bool,
loop_handle: &LoopHandle<'static, State>, loop_handle: &LoopHandle<'static, State>,
shell: Arc<RwLock<Shell>>, shell: Arc<RwLock<Shell>>,
startup_done: Arc<(Mutex<bool>, Condvar)>, startup_done: Arc<AtomicBool>,
) -> Result<Vec<Output>, anyhow::Error> { ) -> Result<Vec<Output>, anyhow::Error> {
if !self.session.is_active() { if !self.session.is_active() {
return Ok(Vec::new()); return Ok(Vec::new());

View file

@ -79,7 +79,7 @@ use std::{
sync::{ sync::{
atomic::{AtomicBool, Ordering}, atomic::{AtomicBool, Ordering},
mpsc::{Receiver, SyncSender}, mpsc::{Receiver, SyncSender},
Arc, Condvar, Mutex, RwLock, Arc, RwLock,
}, },
time::Duration, time::Duration,
}; };
@ -252,7 +252,7 @@ impl Surface {
target_node: DrmNode, target_node: DrmNode,
evlh: &LoopHandle<'static, State>, evlh: &LoopHandle<'static, State>,
shell: Arc<RwLock<Shell>>, shell: Arc<RwLock<Shell>>,
startup_done: Arc<(Mutex<bool>, Condvar)>, startup_done: Arc<AtomicBool>,
) -> Result<Self> { ) -> Result<Self> {
let (tx, rx) = channel::<ThreadCommand>(); let (tx, rx) = channel::<ThreadCommand>();
let (tx2, rx2) = channel::<SurfaceCommand>(); let (tx2, rx2) = channel::<SurfaceCommand>();
@ -441,7 +441,7 @@ fn surface_thread(
active: Arc<AtomicBool>, active: Arc<AtomicBool>,
thread_sender: Sender<SurfaceCommand>, thread_sender: Sender<SurfaceCommand>,
thread_receiver: Channel<ThreadCommand>, thread_receiver: Channel<ThreadCommand>,
startup_done: Arc<(Mutex<bool>, Condvar)>, startup_done: Arc<AtomicBool>,
) -> Result<()> { ) -> Result<()> {
profiling::register_thread!(format!("Surface Thread {}", output.name())); profiling::register_thread!(format!("Surface Thread {}", output.name()));
@ -517,13 +517,8 @@ fn surface_thread(
state.on_vblank(metadata); state.on_vblank(metadata);
} }
Event::Msg(ThreadCommand::ScheduleRender) => { Event::Msg(ThreadCommand::ScheduleRender) => {
{ if !startup_done.load(Ordering::SeqCst) {
// Wait for start up. return;
let (lock, cvar) = &*startup_done;
// As long as the value inside the `Mutex<bool>` is `false`, we wait.
let _guard = cvar
.wait_while(lock.lock().unwrap(), |startup_done| !*startup_done)
.unwrap();
} }
state.queue_redraw(false); state.queue_redraw(false);
@ -534,6 +529,8 @@ fn surface_thread(
Event::Msg(ThreadCommand::SetMode(mode, result)) => { Event::Msg(ThreadCommand::SetMode(mode, result)) => {
if let Some(compositor) = state.compositor.as_mut() { if let Some(compositor) = state.compositor.as_mut() {
let _ = result.send(compositor.use_mode(mode).map_err(Into::into)); let _ = result.send(compositor.use_mode(mode).map_err(Into::into));
} else {
let _ = result.send(Err(anyhow::anyhow!("Set mode with inactive surface")));
} }
} }
Event::Closed | Event::Msg(ThreadCommand::End) => { Event::Closed | Event::Msg(ThreadCommand::End) => {

View file

@ -68,10 +68,13 @@ pub fn init_backend_auto(
{ {
{ {
let (lock, cvar) = &*state.common.startup_done; state
let mut startup = lock.lock().unwrap(); .common
*startup = true; .startup_done
cvar.notify_all(); .store(true, std::sync::atomic::Ordering::SeqCst);
for output in state.common.shell.read().unwrap().outputs() {
state.backend.schedule_render(&output);
}
} }
} }
} }

View file

@ -28,7 +28,7 @@ use std::{
collections::HashMap, collections::HashMap,
fs::OpenOptions, fs::OpenOptions,
path::PathBuf, path::PathBuf,
sync::{Arc, Condvar, Mutex, RwLock}, sync::{atomic::AtomicBool, Arc, RwLock},
}; };
use tracing::{debug, error, info, warn}; use tracing::{debug, error, info, warn};
@ -322,7 +322,7 @@ impl Config {
loop_handle: &LoopHandle<'static, State>, loop_handle: &LoopHandle<'static, State>,
workspace_state: &mut WorkspaceUpdateGuard<'_, State>, workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
xdg_activation_state: &XdgActivationState, xdg_activation_state: &XdgActivationState,
startup_done: Arc<(Mutex<bool>, Condvar)>, startup_done: Arc<AtomicBool>,
) { ) {
let outputs = output_state.outputs().collect::<Vec<_>>(); let outputs = output_state.outputs().collect::<Vec<_>>();
let mut infos = outputs let mut infos = outputs

View file

@ -101,7 +101,7 @@ use std::{
collections::HashSet, collections::HashSet,
ffi::OsString, ffi::OsString,
process::Child, process::Child,
sync::{Arc, Condvar, Mutex, Once, RwLock}, sync::{atomic::AtomicBool, Arc, Mutex, Once, RwLock},
time::Duration, time::Duration,
}; };
@ -174,7 +174,7 @@ pub struct Common {
pub shell: Arc<RwLock<Shell>>, pub shell: Arc<RwLock<Shell>>,
pub clock: Clock<Monotonic>, pub clock: Clock<Monotonic>,
pub startup_done: Arc<(Mutex<bool>, Condvar)>, pub startup_done: Arc<AtomicBool>,
pub should_stop: bool, pub should_stop: bool,
pub local_offset: time::UtcOffset, pub local_offset: time::UtcOffset,
pub gesture_state: Option<GestureState>, pub gesture_state: Option<GestureState>,
@ -274,7 +274,7 @@ impl BackendData {
shell: Arc<RwLock<Shell>>, shell: Arc<RwLock<Shell>>,
workspace_state: &mut WorkspaceUpdateGuard<'_, State>, workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
xdg_activation_state: &XdgActivationState, xdg_activation_state: &XdgActivationState,
startup_done: Arc<(Mutex<bool>, Condvar)>, startup_done: Arc<AtomicBool>,
) -> Result<(), anyhow::Error> { ) -> Result<(), anyhow::Error> {
let result = match self { let result = match self {
BackendData::Kms(ref mut state) => { BackendData::Kms(ref mut state) => {
@ -510,7 +510,7 @@ impl State {
local_offset, local_offset,
clock, clock,
startup_done: Arc::new((Mutex::new(false), Condvar::new())), startup_done: Arc::new(AtomicBool::new(false)),
should_stop: false, should_stop: false,
gesture_state: None, gesture_state: None,