(
endpoint: &str,
timeout: Duration,
)
| 1397 | |
| 1398 | #[cfg(windows)] |
| 1399 | async fn connect_owner_pipe( |
| 1400 | endpoint: &str, |
| 1401 | timeout: Duration, |
| 1402 | ) -> std::io::Result<tokio::net::windows::named_pipe::NamedPipeClient> { |
| 1403 | use tokio::net::windows::named_pipe::ClientOptions; |
| 1404 | use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY; |
| 1405 | |
| 1406 | // A live server can temporarily have no listening instance when several |
| 1407 | // hooks connect at once. Retry acquisition before sending any frame; a busy |
| 1408 | // pipe is not evidence that the owner died or needs another bootstrap. |
| 1409 | let started = tokio::time::Instant::now(); |
| 1410 | loop { |
| 1411 | match ClientOptions::new().open(endpoint) { |
| 1412 | Err(error) |
| 1413 | if error.raw_os_error() == Some(ERROR_PIPE_BUSY as i32) |
| 1414 | && started.elapsed() < timeout => |
| 1415 | { |
| 1416 | tokio::time::sleep( |
| 1417 | START_RETRY_DELAY.min(timeout.saturating_sub(started.elapsed())), |
| 1418 | ) |
| 1419 | .await; |
| 1420 | } |
| 1421 | result => return result, |
| 1422 | } |
| 1423 | } |
| 1424 | } |
| 1425 | |
| 1426 | #[cfg(unix)] |
| 1427 | async fn run_server(endpoint: &str, store: Arc<RedbChangeStore>) -> anyhow::Result<()> { |
no test coverage detected