From Rust 1.78, `Waker::will_wake` tests equality by comparing the VTable
pointers rather than the content of the VTable.
Unfortunately, this exposes some instability in the code generation
which sometimes causes several VTables to be instantiated in memory for
the same generic parameters. This can in turn defeat `Waker::will_wake`
if e.g. `Waker::clone` and `Waker::wake_by_*` end up with different
pointers.
The problemt is hopefully addressed by preventing inlining of the VTable
generation function. A test has been added to try to detect regression,
though the test may not be 100% reliable.
Small changes and cleanups to prepare the RPC work.
Apart from some internal refactoring, this PR introduces improved `EventSlot` and `EventQueue` (the later was renamed from `EventStream`) which can be connected to several outputs at the same time. They are now unified under the common `EventSink` public trait. The new `Output::connect_sink` replaces and generalizes the former `Output::connect_slot` and `Output::connect_stream` to any type implementing `EventSink`.
The `schedule_*event_in` and `schedule_*event_at` pairs of methods are
each merged into a single overloaded method accepting either a relative
`Duration`or an absolute `MonotonicTime`.
Following to the modification of the event cancellation logic, the
simulator no longer needs to remove key-value pairs from the priority
queue. For this reason, a standard binary heap can now be used.
This is a pretty large patch that impacts the API.
Until now, it was not possible to cancel events that were scheduled for
the current simulation time slice, making it necessary for the user to
use complex workarounds (see former version of the espresso machine
example).
The new implementation makes this possible but the generation of a key
associated to an event has now a non-negligible cost (basicaly it
creates three references to an Arc). For this reason, the API now
defaults to NOT creating a key, and new methods were added for
situations when the event may need to be cancelled and a key is
necessary.
See the much simplified implementation of the espresso machine example
for a motivating case.