1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Copyright (c) 2026 Mike Grier
//! Signalling one object and waiting on another in one step: `SignalObjectAndWait`.
use io;
use ;
use Duration;
use SignalObjectAndWait;
use crateEvent;
use crate;
/// An object [`signal_object_and_wait`] can signal: an event, a semaphore or a mutex.
///
/// What a type implementing this promises is that signalling its handle is something the call can
/// do, so a handle that cannot signal is refused when it is passed, not when the call fails. The
/// wait-only handle ([`WaitOnlyEvent`](crate::WaitOnlyEvent)) does not implement it, and the
/// compiler says so:
///
/// ```compile_fail,E0277
/// use win_sync_sys::{Alertable, Event, ResetMode, signal_object_and_wait};
///
/// let ping = Event::new(ResetMode::Auto, false)?;
/// let waiter = ping.try_clone_wait_only()?;
/// let pong = Event::new(ResetMode::Auto, true)?;
/// // A wait-only handle cannot be signalled.
/// signal_object_and_wait(&waiter, &pong, None, Alertable::No)?;
/// # Ok::<(), std::io::Error>(())
/// ```
///
/// It is not sealed: a handle that implements it and cannot in fact be signalled gets the error
/// from the call, not undefined behaviour.
/// Signal `signal`, then wait for `wait`, as one step with nothing able to happen between the two:
/// `SignalObjectAndWait`.
///
/// It is one call to the kernel where a `set` followed by a wait is two, which is what Microsoft
/// offers it for: a handshake between two threads without the context switch the second call can
/// cost.
///
/// `signal` is set if it is an event, released once if it is a semaphore, and released if it is a
/// mutex the calling thread owns. A wait that times out or is alerted has **still signalled**: the
/// signal is not undone. The outcomes are those of a wait on one object, with `wait` changed as
/// [`wait_for_single_object`](crate::wait_for_single_object) describes.
///
/// # Errors
///
/// [`io::ErrorKind::InvalidInput`] for a timeout the call cannot express, before anything is
/// signalled. Otherwise the error from `GetLastError`, and then **nothing was waited on and the
/// signal may or may not have been sent**: the call reports one failure for either half, so a
/// caller that needs to know checks the object. Access denied for a `signal` handle without the
/// right to modify it, or for a `wait` handle without `SYNCHRONIZE`; invalid handle for one that
/// is not an object the call can signal.