mirror of
https://github.com/arabianq/pipewire-soundpad.git
synced 2026-04-28 06:21:23 +00:00
Fix daemon autostart issue caused by sync pipewire retry loop (#43)
At boot time, PipeWire takes some time to register the `pwsp-daemon` and `pwsp-virtual-mic` devices. Previously, the daemon's retry loop for `link_player_to_virtual_mic()` was synchronous and limited to 5 attempts (1.5 seconds total). This caused systemd autostarts to fail with a code 1 if the devices were not yet available. This change replaces the synchronous wait with an asynchronous `tokio::spawn` task. It will retry the link attempt up to 60 times with a 1-second delay without blocking the startup of the rest of the daemon. This prevents it from exiting abruptly during autostart. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
6114b9a7f8
commit
f01a0e656c
+17
-10
@@ -31,16 +31,20 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
eprintln!("Failed to initialize audio player: {}", err);
|
||||
} // Initialize audio player
|
||||
|
||||
let max_retries = 5;
|
||||
for i in 0..=max_retries {
|
||||
match link_player_to_virtual_mic().await {
|
||||
Ok(_) => break,
|
||||
Err(e) => println!("{e}\t{i}/{max_retries}"),
|
||||
}
|
||||
tokio::spawn(async {
|
||||
let max_retries = 60;
|
||||
for i in 0..=max_retries {
|
||||
match link_player_to_virtual_mic().await {
|
||||
Ok(_) => {
|
||||
println!("Successfully linked player to virtual mic.");
|
||||
break;
|
||||
}
|
||||
Err(e) => println!("{e}\t{i}/{max_retries}"),
|
||||
}
|
||||
|
||||
sleep(Duration::from_millis(300 * i)).await;
|
||||
}
|
||||
link_player_to_virtual_mic().await?;
|
||||
sleep(Duration::from_millis(1000)).await;
|
||||
}
|
||||
});
|
||||
|
||||
let runtime_dir = get_runtime_dir();
|
||||
|
||||
@@ -97,7 +101,10 @@ async fn commands_loop(listener: UnixListener) -> Result<(), Box<dyn Error>> {
|
||||
let request_len = u32::from_le_bytes(len_bytes) as usize;
|
||||
|
||||
if request_len > 10 * 1024 * 1024 {
|
||||
eprintln!("Failed to read message from client: request too large ({} bytes)!", request_len);
|
||||
eprintln!(
|
||||
"Failed to read message from client: request too large ({} bytes)!",
|
||||
request_len
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+18
-16
@@ -86,14 +86,15 @@ impl SoundpadGui {
|
||||
.as_ref()
|
||||
.and_then(|cd| dirs.iter().position(|x| x == cd));
|
||||
|
||||
let new_dir_index = match (current_dir_index, arrow_up_pressed, arrow_down_pressed) {
|
||||
(Some(i), true, false) => (i + dirs.len() - 1) % dirs.len(),
|
||||
(Some(i), false, true) => (i + 1) % dirs.len(),
|
||||
(Some(i), true, true) => i,
|
||||
(None, true, _) => dirs.len() - 1,
|
||||
(None, false, true) => 0,
|
||||
_ => return,
|
||||
};
|
||||
let new_dir_index =
|
||||
match (current_dir_index, arrow_up_pressed, arrow_down_pressed) {
|
||||
(Some(i), true, false) => (i + dirs.len() - 1) % dirs.len(),
|
||||
(Some(i), false, true) => (i + 1) % dirs.len(),
|
||||
(Some(i), true, true) => i,
|
||||
(None, true, _) => dirs.len() - 1,
|
||||
(None, false, true) => 0,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
self.open_dir(&dirs[new_dir_index]);
|
||||
} else if self.app_state.current_dir.is_some() {
|
||||
@@ -109,14 +110,15 @@ impl SoundpadGui {
|
||||
.as_ref()
|
||||
.and_then(|f| files.iter().position(|x| x == f));
|
||||
|
||||
let new_files_index = match (current_files_index, arrow_up_pressed, arrow_down_pressed) {
|
||||
(Some(i), true, false) => (i + files.len() - 1) % files.len(),
|
||||
(Some(i), false, true) => (i + 1) % files.len(),
|
||||
(Some(i), true, true) => i,
|
||||
(None, true, _) => files.len() - 1,
|
||||
(None, false, true) => 0,
|
||||
_ => return,
|
||||
};
|
||||
let new_files_index =
|
||||
match (current_files_index, arrow_up_pressed, arrow_down_pressed) {
|
||||
(Some(i), true, false) => (i + files.len() - 1) % files.len(),
|
||||
(Some(i), false, true) => (i + 1) % files.len(),
|
||||
(Some(i), true, true) => i,
|
||||
(None, true, _) => files.len() - 1,
|
||||
(None, false, true) => 0,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
self.app_state.selected_file = Some(files[new_files_index].clone());
|
||||
}
|
||||
|
||||
+8
-2
@@ -58,7 +58,10 @@ impl SoundpadGui {
|
||||
|
||||
pub fn play_toggle(&mut self) {
|
||||
let (new_state, request) = {
|
||||
let guard = self.audio_player_state_shared.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let guard = self
|
||||
.audio_player_state_shared
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
match guard.state {
|
||||
PlayerState::Playing => (Some(PlayerState::Paused), Some(Request::pause(None))),
|
||||
PlayerState::Paused => (Some(PlayerState::Playing), Some(Request::resume(None))),
|
||||
@@ -71,7 +74,10 @@ impl SoundpadGui {
|
||||
}
|
||||
|
||||
if let Some(state) = new_state {
|
||||
let mut guard = self.audio_player_state_shared.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let mut guard = self
|
||||
.audio_player_state_shared
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
guard.new_state = Some(state.clone());
|
||||
guard.state = state;
|
||||
}
|
||||
|
||||
+4
-1
@@ -77,7 +77,10 @@ impl App for SoundpadGui {
|
||||
|
||||
// Sync audio player state
|
||||
{
|
||||
let guard = self.audio_player_state_shared.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let guard = self
|
||||
.audio_player_state_shared
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
self.audio_player_state = guard.clone();
|
||||
}
|
||||
|
||||
|
||||
@@ -280,16 +280,18 @@ impl AudioPlayer {
|
||||
) -> Result<u32, Box<dyn Error>> {
|
||||
let path_buf = file_path.to_path_buf();
|
||||
|
||||
let decoder_result = tokio::task::spawn_blocking(move || -> Result<_, Box<dyn Error + Send + Sync>> {
|
||||
if !path_buf.exists() {
|
||||
return Err(format!("File does not exist: {}", path_buf.display()).into());
|
||||
}
|
||||
let decoder_result =
|
||||
tokio::task::spawn_blocking(move || -> Result<_, Box<dyn Error + Send + Sync>> {
|
||||
if !path_buf.exists() {
|
||||
return Err(format!("File does not exist: {}", path_buf.display()).into());
|
||||
}
|
||||
|
||||
let file = fs::File::open(&path_buf)?;
|
||||
let decoder = Decoder::try_from(file).map_err(|e| Box::new(e) as Box<dyn Error + Send + Sync>)?;
|
||||
Ok(decoder)
|
||||
})
|
||||
.await?;
|
||||
let file = fs::File::open(&path_buf)?;
|
||||
let decoder = Decoder::try_from(file)
|
||||
.map_err(|e| Box::new(e) as Box<dyn Error + Send + Sync>)?;
|
||||
Ok(decoder)
|
||||
})
|
||||
.await?;
|
||||
|
||||
match decoder_result {
|
||||
Ok(source) => {
|
||||
|
||||
Reference in New Issue
Block a user