mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-06-30 15:35:33 +02:00
fix(single-instance): Yield unix listener in macos (#3466)
* Use tokio UnixListener so the task can yield and release the thread * use standard unix listener, convert to non blocking and cast into tokio yielding one * Create fix-yield-single-instance-macos.md * Update .changes/fix-yield-single-instance-macos.md Co-authored-by: Fabian-Lars <30730186+FabianLars@users.noreply.github.com> * use net feature in Tokio dependency * Use tokio UnixListener::bind, inside the tokio task --------- Co-authored-by: Fabian-Lars <30730186+FabianLars@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
"single-instance": patch
|
||||
---
|
||||
Fix blocked thread on the single-instance plugin for MacOS: replace standard `UnixListener` with `tokio::net::UnixListener`, so the task can yield.
|
||||
Generated
+1
@@ -6793,6 +6793,7 @@ dependencies = [
|
||||
"tauri",
|
||||
"tauri-plugin-deep-link",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"windows-sys 0.60.2",
|
||||
"zbus",
|
||||
|
||||
@@ -24,6 +24,7 @@ tracing = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tauri-plugin-deep-link = { path = "../deep-link", version = "2.4.9", optional = true }
|
||||
semver = { version = "1", optional = true }
|
||||
tokio = { version = "1", features = ["net"] }
|
||||
|
||||
[target."cfg(target_os = \"windows\")".dependencies.windows-sys]
|
||||
version = "0.60"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::{
|
||||
io::{BufWriter, Error, ErrorKind, Read, Write},
|
||||
os::unix::net::{UnixListener, UnixStream},
|
||||
io::{BufWriter, Error, ErrorKind, Write},
|
||||
os::unix::net::UnixStream,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ use tauri::{
|
||||
plugin::{self, TauriPlugin},
|
||||
AppHandle, Config, Manager, RunEvent, Runtime,
|
||||
};
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
||||
pub fn init<R: Runtime>(cb: Box<SingleInstanceCallback<R>>) -> TauriPlugin<R> {
|
||||
plugin::Builder::new("single-instance")
|
||||
@@ -31,7 +32,7 @@ pub fn init<R: Runtime>(cb: Box<SingleInstanceCallback<R>>) -> TauriPlugin<R> {
|
||||
ErrorKind::NotFound | ErrorKind::ConnectionRefused => {
|
||||
// This process claims itself as singleton as likely none exists
|
||||
socket_cleanup(&socket);
|
||||
listen_for_other_instances(&socket, app.clone(), cb);
|
||||
listen_for_other_instances(socket, app.clone(), cb);
|
||||
}
|
||||
_ => {
|
||||
tracing::debug!(
|
||||
@@ -92,42 +93,40 @@ fn notify_singleton(socket: &PathBuf) -> Result<(), Error> {
|
||||
}
|
||||
|
||||
fn listen_for_other_instances<A: Runtime>(
|
||||
socket: &PathBuf,
|
||||
socket: PathBuf,
|
||||
app: AppHandle<A>,
|
||||
mut cb: Box<SingleInstanceCallback<A>>,
|
||||
) {
|
||||
match UnixListener::bind(socket) {
|
||||
Ok(listener) => {
|
||||
tauri::async_runtime::spawn(async move {
|
||||
for stream in listener.incoming() {
|
||||
match stream {
|
||||
Ok(mut stream) => {
|
||||
let mut s = String::new();
|
||||
match stream.read_to_string(&mut s) {
|
||||
Ok(_) => {
|
||||
let (cwd, args) = s.split_once("\0\0").unwrap_or_default();
|
||||
let args: Vec<String> =
|
||||
args.split('\0').map(String::from).collect();
|
||||
cb(app.app_handle(), args, cwd.to_string());
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::debug!("single_instance failed to be notified: {e}")
|
||||
}
|
||||
tauri::async_runtime::spawn(async move {
|
||||
match tokio::net::UnixListener::bind(socket) {
|
||||
Ok(listener) => loop {
|
||||
match listener.accept().await {
|
||||
Ok((mut stream, _addr)) => {
|
||||
let mut s = String::new();
|
||||
match stream.read_to_string(&mut s).await {
|
||||
Ok(_) => {
|
||||
let (cwd, args) = s.split_once("\0\0").unwrap_or_default();
|
||||
let args: Vec<String> =
|
||||
args.split('\0').map(String::from).collect();
|
||||
cb(app.app_handle(), args, cwd.to_string());
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::debug!("single_instance failed to be notified: {e}")
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::debug!("single_instance failed to be notified: {}", err);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::debug!("single_instance failed to be notified: {}", err);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
Err(err) => {
|
||||
tracing::error!(
|
||||
"single_instance failed to listen to other processes - launching normally: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!(
|
||||
"single_instance failed to listen to other processes - launching normally: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user