Skip to main content

ridl_loopback/
handle.rs

1//! The six handle types and their port implementations.
2//!
3//! A **port role** is one port trait, and a runtime presents one handle type
4//! per role rather than one type implementing them all (ADR-0021 decision 12).
5//! The six here group eleven roles the way that decision derives the
6//! threading split: the five roles with a `&mut self` method take a handle
7//! each, and the six whose methods all take `&self` share one, because they
8//! are exactly the roles several threads may hold at once. The twelfth port
9//! trait, `Wakeable`, is on every handle, because each handle wakes its own
10//! waiters. Every handle here
11//! holds the same `Arc<Mutex<Store>>` and its own copy of the
12//! [`CatalogRef`](ridl_rt::contract::CatalogRef) the runtime was built with,
13//! so `Attached::catalog` can return a reference without reaching through the
14//! lock. Every handle also carries the encoding its runtime's ports carry, as
15//! the type parameter `E` it shares with [`Loopback`](crate::Loopback), and
16//! implements `Encoded` with it; the parameter is a `PhantomData` field and
17//! takes part in no method, because the bytes are opaque to this runtime.
18//!
19//! Every handle implements `Attached`, which every port trait but `Clock` and
20//! `Wakeable` has as a supertrait, `Encoded`, and `Wakeable`. The table lists
21//! what each handle adds to them, and the split follows the receiver of those
22//! methods, as ADR-0021 decision 12 derives it:
23//!
24//! | Handle            | Port roles beside `Attached`, `Encoded` and `Wakeable`                        | Kinds of key it stores                            | Threading     |
25//! | ----------------- | ----------------------------------------------------------------------------- | ------------------------------------------------- | ------------- |
26//! | [`ReaderHandle`]  | `Clock`, `SignalReader`, `FixedReader`, `ScannableSignals`, `CoherentSignals` | none                                              | `Send + Sync` |
27//! | [`WriterHandle`]  | `SignalWriter`                                                                | none                                              | `Send`        |
28//! | [`SourceHandle`]  | `EventSource`                                                                 | `Event`, one waker                                | `Send`        |
29//! | [`SinkHandle`]    | `EventSink`                                                                   | none                                              | `Send`        |
30//! | [`CallerHandle`]  | `Clock`, `Caller`                                                             | `Outcome`, kept with each call; `Slot`, one waker | `Send`        |
31//! | [`HandlerHandle`] | `Handler`                                                                     | `Claim`, one waker                                | `Send`        |
32//!
33//! A handle stores a waker only under a kind of key one of its roles
34//! observes. For `Event` and `Claim` that is one waker per kind, and a
35//! change to any key of that kind wakes it (ADR-0021 decision 13). An
36//! `Outcome` waker is per call: it is kept with its call, and no change but
37//! that call's settlement, its `forget`, or the drop of the caller handle
38//! that sent it wakes it; a displacement by another task does, as for every
39//! kind. A caller stores one `Slot` waker, woken at once while a slot of the
40//! call table is free, and otherwise by the next reclaim of a slot — a
41//! `forget`, a settlement of a forgotten call, a caller handle's drop, or a
42//! handler handle's drop while it holds a claim whose call was forgotten —
43//! which wakes every other caller's `Slot` waker. A registration
44//! under any other kind is woken at once, because nothing that handle could
45//! read changes under it, and a stored waker would never be woken.
46//!
47//! Every method on the reader handle takes `&self`, so several threads may
48//! read one store at once; every other handle carries a trait with a
49//! `&mut self` method and is driven by one thread at a time. Neither property
50//! is declared: both are derived by the compiler from the fields, and
51//! `crates/ridl-loopback/src/lib.rs` asserts them at compile time.
52
53use std::collections::BTreeMap;
54use std::marker::PhantomData;
55use std::sync::{Arc, Mutex, MutexGuard};
56use std::task::Waker;
57
58use ridl_rt::contract::{CatalogRef, InterfaceNo, Ordinal};
59use ridl_rt::encoding::{Encoding, FlatBuffers};
60use ridl_rt::error::CallError;
61use ridl_rt::port::{
62    Attached, Caller, Changed, Claim, ClaimId, Clock, CoherentSignals, Correlation, Encoded,
63    EventSink, EventSource, FixedReader, Handler, Interest, RaiseError, RawOccurrence, RawSample,
64    ReadError, ScannableSignals, SendError, ServeError, SettleError, SignalReader, SignalWriter,
65    SubscribeError, Wakeable, Watermark, WriteError,
66};
67use ridl_rt::sample::Timestamp;
68use ridl_rt::trace::TraceContext;
69
70use crate::store::{CallKind, Key, Staged, Store};
71
72/// The shared store, as every handle holds it.
73pub(crate) type Shared = Arc<Mutex<Store>>;
74
75/// Takes the one lock.
76///
77/// A panic while the lock is held poisons it. This runtime recovers the guard
78/// rather than propagating the poison, because every critical section here is
79/// a read or a write of the maps that leaves them well formed, and a poisoned
80/// lock would otherwise turn one panic in one test into a panic in every later
81/// port call over the same runtime.
82pub(crate) fn lock(shared: &Shared) -> MutexGuard<'_, Store> {
83    shared
84        .lock()
85        .unwrap_or_else(|poisoned| poisoned.into_inner())
86}
87
88/// Takes the one lock, runs `f` with a list of wakers to wake, releases the
89/// lock, and then wakes each waker `f` put on the list.
90///
91/// A waker runs code the runtime does not control — an executor's scheduling,
92/// or a test's own — and that code may call a port method on this runtime. So
93/// no waker is woken while the lock is held.
94pub(crate) fn locked<R>(shared: &Shared, f: impl FnOnce(&mut Store, &mut Vec<Waker>) -> R) -> R {
95    let mut wake = Vec::new();
96    let result = {
97        let mut store = lock(shared);
98        f(&mut store, &mut wake)
99    };
100    for waker in wake {
101        waker.wake();
102    }
103    result
104}
105
106/// `Wakeable` on a handle none of whose roles observes any key: every
107/// registration is woken at once.
108fn wake_at_once(waker: &Waker) {
109    waker.wake_by_ref();
110}
111
112// ---------------------------------------------------------------------------
113// The reader handle
114// ---------------------------------------------------------------------------
115
116/// The `&self` port roles: `Attached`, `Clock`, `SignalReader`,
117/// `FixedReader`, and the two signal extensions.
118///
119/// It is `Send + Sync`, so several threads may hold one and read at once, and
120/// a face that needs only `SignalReader` can be built over this handle
121/// directly rather than over the aggregate: like every handle, it carries the
122/// runtime's encoding `E`, which such a face reads from it.
123pub struct ReaderHandle<E: Encoding = FlatBuffers> {
124    shared: Shared,
125    catalog: CatalogRef,
126    encoding: PhantomData<E>,
127}
128
129impl<E: Encoding> ReaderHandle<E> {
130    pub(crate) fn new(shared: Shared, catalog: CatalogRef) -> Self {
131        ReaderHandle {
132            shared,
133            catalog,
134            encoding: PhantomData,
135        }
136    }
137}
138
139impl<E: Encoding> Attached for ReaderHandle<E> {
140    fn catalog(&self) -> &CatalogRef {
141        &self.catalog
142    }
143}
144
145impl<E: Encoding> Encoded for ReaderHandle<E> {
146    type Encoding = E;
147}
148
149impl<E: Encoding> Clock for ReaderHandle<E> {
150    fn now(&self) -> Timestamp {
151        lock(&self.shared).now()
152    }
153}
154
155impl<E: Encoding> Wakeable for ReaderHandle<E> {
156    fn wake_on(&self, _: Interest, waker: &Waker) {
157        wake_at_once(waker);
158    }
159}
160
161impl<E: Encoding> SignalReader for ReaderHandle<E> {
162    fn read(
163        &self,
164        iface: InterfaceNo,
165        ord: Ordinal,
166        out: &mut [u8],
167    ) -> Result<RawSample, ReadError> {
168        lock(&self.shared).read(iface, ord, out)
169    }
170}
171
172impl<E: Encoding> FixedReader for ReaderHandle<E> {
173    fn read_fixed(
174        &self,
175        iface: InterfaceNo,
176        ord: Ordinal,
177        out: &mut [u8],
178    ) -> Result<usize, ReadError> {
179        lock(&self.shared).read_fixed(iface, ord, out)
180    }
181}
182
183impl<E: Encoding> ScannableSignals for ReaderHandle<E> {
184    fn generation(&self, iface: InterfaceNo) -> u64 {
185        lock(&self.shared).generation(iface)
186    }
187
188    fn scan(&self, marks: &mut [Watermark], out: &mut [Changed]) -> usize {
189        lock(&self.shared).scan(marks, out)
190    }
191}
192
193impl<E: Encoding> CoherentSignals for ReaderHandle<E> {
194    fn read_coherent(
195        &self,
196        iface: InterfaceNo,
197        ords: &[Ordinal],
198        out: &mut [u8],
199        samples: &mut [RawSample],
200    ) -> Result<usize, ReadError> {
201        lock(&self.shared).read_coherent(iface, ords, out, samples)
202    }
203}
204
205// ---------------------------------------------------------------------------
206// The writer handle
207// ---------------------------------------------------------------------------
208
209/// The `SignalWriter` port role.
210///
211/// The staged changes and the per channel sequence counters live on the
212/// handle, not in the store: staging is one provider's private state until its
213/// `commit`, and a sequence number is assigned by the sender (ridl §3.1).
214pub struct WriterHandle<E: Encoding = FlatBuffers> {
215    shared: Shared,
216    catalog: CatalogRef,
217    staged: BTreeMap<Key, Staged>,
218    seqs: BTreeMap<Key, u64>,
219    encoding: PhantomData<E>,
220}
221
222impl<E: Encoding> WriterHandle<E> {
223    pub(crate) fn new(shared: Shared, catalog: CatalogRef) -> Self {
224        WriterHandle {
225            shared,
226            catalog,
227            staged: BTreeMap::new(),
228            seqs: BTreeMap::new(),
229            encoding: PhantomData,
230        }
231    }
232}
233
234impl<E: Encoding> Attached for WriterHandle<E> {
235    fn catalog(&self) -> &CatalogRef {
236        &self.catalog
237    }
238}
239
240impl<E: Encoding> Encoded for WriterHandle<E> {
241    type Encoding = E;
242}
243
244impl<E: Encoding> SignalWriter for WriterHandle<E> {
245    fn set(&mut self, iface: InterfaceNo, ord: Ordinal, bytes: &[u8]) -> Result<(), WriteError> {
246        self.staged
247            .insert((iface, ord), Staged::Set(bytes.to_vec()));
248        Ok(())
249    }
250
251    fn invalidate(&mut self, iface: InterfaceNo, ord: Ordinal) -> Result<(), WriteError> {
252        self.staged.insert((iface, ord), Staged::Invalidate);
253        Ok(())
254    }
255
256    fn touch(&mut self, iface: InterfaceNo, ord: Ordinal) -> Result<(), WriteError> {
257        // A touch re-affirms the current value. It stages one only when
258        // nothing else is staged for the channel: a `set` or an `invalidate`
259        // already staged is itself a publication, and a re-affirmation adds
260        // nothing to it. Replacing one here would discard a value this writer
261        // staged, which is not what `touch` means. A later `set` or
262        // `invalidate` does replace a staged touch, because each is a newer
263        // decision about the same channel.
264        self.staged.entry((iface, ord)).or_insert(Staged::Touch);
265        Ok(())
266    }
267
268    fn commit(&mut self) {
269        lock(&self.shared).commit(&mut self.staged, &mut self.seqs);
270    }
271}
272
273impl<E: Encoding> Wakeable for WriterHandle<E> {
274    fn wake_on(&self, _: Interest, waker: &Waker) {
275        wake_at_once(waker);
276    }
277}
278
279// ---------------------------------------------------------------------------
280// The event handles
281// ---------------------------------------------------------------------------
282
283/// The `EventSource` port role: one subscription set and one queue, both in
284/// the store under this handle's identity.
285///
286/// Each source handle receives its own copy of every occurrence raised while
287/// it is subscribed, so two consumers of one event never consume each other's
288/// occurrences.
289pub struct SourceHandle<E: Encoding = FlatBuffers> {
290    shared: Shared,
291    catalog: CatalogRef,
292    id: usize,
293    encoding: PhantomData<E>,
294}
295
296impl<E: Encoding> SourceHandle<E> {
297    pub(crate) fn new(shared: Shared, catalog: CatalogRef) -> Self {
298        let id = lock(&shared).open_source();
299        SourceHandle {
300            shared,
301            catalog,
302            id,
303            encoding: PhantomData,
304        }
305    }
306}
307
308/// The source's waker is dropped after the lock is released: it may be the
309/// last reference to a task that owns another handle of this runtime, and
310/// that handle's own `Drop` takes the lock.
311impl<E: Encoding> Drop for SourceHandle<E> {
312    fn drop(&mut self) {
313        let waiters = lock(&self.shared).close_source(self.id);
314        drop(waiters);
315    }
316}
317
318impl<E: Encoding> Attached for SourceHandle<E> {
319    fn catalog(&self) -> &CatalogRef {
320        &self.catalog
321    }
322}
323
324impl<E: Encoding> Encoded for SourceHandle<E> {
325    type Encoding = E;
326}
327
328impl<E: Encoding> EventSource for SourceHandle<E> {
329    fn subscribe(&mut self, iface: InterfaceNo, ords: &[Ordinal]) -> Result<(), SubscribeError> {
330        lock(&self.shared).subscribe(self.id, iface, ords);
331        Ok(())
332    }
333
334    fn unsubscribe(&mut self, iface: InterfaceNo, ords: &[Ordinal]) {
335        lock(&self.shared).unsubscribe(self.id, iface, ords);
336    }
337
338    fn next(&mut self, out: &mut [u8]) -> Result<Option<RawOccurrence>, ReadError> {
339        lock(&self.shared).next_event(self.id, out)
340    }
341}
342
343/// Stores one `Event` waker, whatever interface it was registered under, woken
344/// by any raise that queues an occurrence for this source.
345impl<E: Encoding> Wakeable for SourceHandle<E> {
346    fn wake_on(&self, what: Interest, waker: &Waker) {
347        match what {
348            Interest::Event(_) => locked(&self.shared, |store, wake| {
349                store.wait_event(self.id, what, waker, wake);
350            }),
351            Interest::Outcome(_) | Interest::Slot | Interest::Claim(_) => wake_at_once(waker),
352        }
353    }
354}
355
356/// The `EventSink` port role.
357///
358/// The sequence counters are the handle's own, one per event channel, for the
359/// same reason the writer handle's are: ridl §3.1 scopes the number to the
360/// channel and has the sender assign it. One counter for the whole handle
361/// would make a consumer subscribed to some of this sink's events see a gap in
362/// `seq` where nothing was lost, and `EventSource::next` states that a gap is
363/// a loss.
364pub struct SinkHandle<E: Encoding = FlatBuffers> {
365    shared: Shared,
366    catalog: CatalogRef,
367    seqs: BTreeMap<Key, u64>,
368    encoding: PhantomData<E>,
369}
370
371impl<E: Encoding> SinkHandle<E> {
372    pub(crate) fn new(shared: Shared, catalog: CatalogRef) -> Self {
373        SinkHandle {
374            shared,
375            catalog,
376            seqs: BTreeMap::new(),
377            encoding: PhantomData,
378        }
379    }
380
381    fn take_seq(&mut self, key: Key) -> u64 {
382        let counter = self.seqs.entry(key).or_insert(0);
383        *counter += 1;
384        *counter
385    }
386}
387
388impl<E: Encoding> Attached for SinkHandle<E> {
389    fn catalog(&self) -> &CatalogRef {
390        &self.catalog
391    }
392}
393
394impl<E: Encoding> Encoded for SinkHandle<E> {
395    type Encoding = E;
396}
397
398impl<E: Encoding> EventSink for SinkHandle<E> {
399    fn raise(
400        &mut self,
401        iface: InterfaceNo,
402        ord: Ordinal,
403        bytes: &[u8],
404        trace: Option<TraceContext>,
405    ) -> Result<(), RaiseError> {
406        let seq = self.take_seq((iface, ord));
407        locked(&self.shared, |store, wake| {
408            store.raise(iface, ord, bytes, seq, trace, wake);
409        });
410        Ok(())
411    }
412}
413
414impl<E: Encoding> Wakeable for SinkHandle<E> {
415    fn wake_on(&self, _: Interest, waker: &Waker) {
416        wake_at_once(waker);
417    }
418}
419
420// ---------------------------------------------------------------------------
421// The call handles
422// ---------------------------------------------------------------------------
423
424/// The `Caller` port role.
425///
426/// One counter for the whole handle, not one per channel: on a call the scope
427/// is the caller instance (ADR-0021 decision 5, and driftsys/ridl#308's own
428/// report), so every call this caller sends draws from one sequence. That is
429/// what keeps two callers on one provider from colliding.
430///
431/// The call table is the runtime's, shared by every caller: with
432/// [`Loopback::SLOTS`](crate::Loopback::SLOTS) calls holding a slot, a send
433/// answers [`SendError::Busy`] and draws no sequence number, because nothing
434/// was sent. A call holds its slot from the send until its `forget`, except
435/// that a call forgotten after a handler claimed it keeps the slot until its
436/// settlement.
437pub struct CallerHandle<E: Encoding = FlatBuffers> {
438    shared: Shared,
439    catalog: CatalogRef,
440    id: usize,
441    next_seq: u64,
442    encoding: PhantomData<E>,
443}
444
445impl<E: Encoding> CallerHandle<E> {
446    pub(crate) fn new(shared: Shared, catalog: CatalogRef) -> Self {
447        let id = lock(&shared).open_caller();
448        CallerHandle {
449            shared,
450            catalog,
451            id,
452            next_seq: 0,
453            encoding: PhantomData,
454        }
455    }
456
457    /// Sends one call. The sequence number is drawn only when the table
458    /// admits the call.
459    fn send(
460        &mut self,
461        kind: CallKind,
462        iface: InterfaceNo,
463        ord: Ordinal,
464        args: &[u8],
465        trace: Option<TraceContext>,
466    ) -> Result<Correlation, SendError> {
467        let seq = self.next_seq + 1;
468        let c = locked(&self.shared, |store, wake| {
469            store.send(self.id, kind, (iface, ord), args, seq, trace, wake)
470        })?;
471        self.next_seq = seq;
472        Ok(c)
473    }
474}
475
476/// A dropped caller's `Slot` waker leaves the store, and every call it sent
477/// and did not forget is forgotten, so its slot comes back. The waker is
478/// dropped after the lock is released, as the source's is.
479impl<E: Encoding> Drop for CallerHandle<E> {
480    fn drop(&mut self) {
481        let waiters = locked(&self.shared, |store, wake| {
482            store.close_caller(self.id, wake)
483        });
484        drop(waiters);
485    }
486}
487
488impl<E: Encoding> Attached for CallerHandle<E> {
489    fn catalog(&self) -> &CatalogRef {
490        &self.catalog
491    }
492}
493
494impl<E: Encoding> Encoded for CallerHandle<E> {
495    type Encoding = E;
496}
497
498/// The caller reads the runtime's one clock, so a generated async `Client`
499/// can compute a call's deadline over this handle alone.
500impl<E: Encoding> Clock for CallerHandle<E> {
501    fn now(&self) -> Timestamp {
502        lock(&self.shared).now()
503    }
504}
505
506/// Stores one `Outcome` waker per call, kept with the call and woken by its
507/// settlement, its `forget`, the drop of this handle, or a displacement by
508/// another task. Stores one `Slot` waker, woken at once while a slot is free
509/// and otherwise by the next reclaim.
510impl<E: Encoding> Wakeable for CallerHandle<E> {
511    fn wake_on(&self, what: Interest, waker: &Waker) {
512        match what {
513            Interest::Outcome(c) => locked(&self.shared, |store, wake| {
514                store.wait_outcome(c, waker, wake);
515            }),
516            Interest::Slot => locked(&self.shared, |store, wake| {
517                store.wait_slot(self.id, waker, wake);
518            }),
519            Interest::Event(_) | Interest::Claim(_) => wake_at_once(waker),
520        }
521    }
522}
523
524impl<E: Encoding> Caller for CallerHandle<E> {
525    fn command(
526        &mut self,
527        iface: InterfaceNo,
528        ord: Ordinal,
529        args: &[u8],
530        trace: Option<TraceContext>,
531    ) -> Result<Correlation, SendError> {
532        self.send(CallKind::Command, iface, ord, args, trace)
533    }
534
535    fn query(
536        &mut self,
537        iface: InterfaceNo,
538        ord: Ordinal,
539        args: &[u8],
540        trace: Option<TraceContext>,
541    ) -> Result<Correlation, SendError> {
542        self.send(CallKind::Query, iface, ord, args, trace)
543    }
544
545    fn ack(&mut self, c: Correlation) -> Option<Result<(), CallError>> {
546        lock(&self.shared).ack(c)
547    }
548
549    fn reply(
550        &mut self,
551        c: Correlation,
552        out: &mut [u8],
553    ) -> Result<Option<Result<usize, CallError>>, ReadError> {
554        lock(&self.shared).reply(c, out)
555    }
556
557    fn forget(&mut self, c: Correlation) {
558        locked(&self.shared, |store, wake| store.forget(c, wake));
559    }
560}
561
562/// The `Handler` port role.
563///
564/// A handler that has served nothing is presented every call waiting in the
565/// store; once it has served anything, it is presented only the members it
566/// served, and another handler's calls stay waiting for that handler. A claim
567/// belongs to the handler it was presented to, so another handler's `settle`
568/// of it answers [`SettleError::UnknownClaim`].
569///
570/// The empty set meaning no filter is a deliberate deviation from
571/// [`Handler::serve`], which says delivery starts at the members listed. The
572/// generated `dispatch` never calls `serve`
573/// (`crates/ridl-backend-rust/src/face/dispatch.rs`), so a handler that always filtered
574/// would be presented nothing at all by it. `serve` with an empty slice
575/// records nothing and so leaves the handler unfiltered, the same as never
576/// having called it. [`served`](HandlerHandle::served) reads the set back.
577///
578/// The served set is kept twice: here, for `served` to return a slice, and in
579/// the store, where `next_claim` filters by it and a caller's send reads it to
580/// know which handler to wake. `serve` is the one method that changes it, and
581/// it changes both.
582pub struct HandlerHandle<E: Encoding = FlatBuffers> {
583    shared: Shared,
584    catalog: CatalogRef,
585    id: usize,
586    served: Vec<Key>,
587    encoding: PhantomData<E>,
588}
589
590impl<E: Encoding> HandlerHandle<E> {
591    pub(crate) fn new(shared: Shared, catalog: CatalogRef) -> Self {
592        let id = lock(&shared).open_handler();
593        HandlerHandle {
594            shared,
595            catalog,
596            id,
597            served: Vec::new(),
598            encoding: PhantomData,
599        }
600    }
601
602    /// The members `serve` was called with, in the order they were served,
603    /// with no duplicate.
604    #[must_use]
605    pub fn served(&self) -> &[(InterfaceNo, Ordinal)] {
606        &self.served
607    }
608}
609
610/// A claim this handler has taken and not settled returns to the waiting
611/// calls, and every handler that serves its member is woken. A claim it was
612/// only offered, through `ReadError::ShortClaim`, never left the waiting calls,
613/// so it is neither re-inserted nor woken for (driftsys/ridl#569). A claim whose
614/// call the caller forgot is withdrawn instead: its slot is reclaimed, and no
615/// handler is presented it again or woken for it. The handler's waker is
616/// dropped after the lock is released, as the source's is.
617impl<E: Encoding> Drop for HandlerHandle<E> {
618    fn drop(&mut self) {
619        let waiters = locked(&self.shared, |store, wake| {
620            store.close_handler(self.id, wake)
621        });
622        drop(waiters);
623    }
624}
625
626impl<E: Encoding> Attached for HandlerHandle<E> {
627    fn catalog(&self) -> &CatalogRef {
628        &self.catalog
629    }
630}
631
632impl<E: Encoding> Encoded for HandlerHandle<E> {
633    type Encoding = E;
634}
635
636impl<E: Encoding> Handler for HandlerHandle<E> {
637    fn serve(&mut self, iface: InterfaceNo, ords: &[Ordinal]) -> Result<(), ServeError> {
638        for ord in ords {
639            if !self.served.contains(&(iface, *ord)) {
640                self.served.push((iface, *ord));
641            }
642        }
643        locked(&self.shared, |store, wake| {
644            store.serve(self.id, iface, ords, wake);
645        });
646        Ok(())
647    }
648
649    fn next_claim(&mut self, out: &mut [u8]) -> Result<Option<Claim>, ReadError> {
650        lock(&self.shared).next_claim(self.id, out)
651    }
652
653    fn settle(
654        &mut self,
655        claim: ClaimId,
656        outcome: Result<&[u8], CallError>,
657    ) -> Result<(), SettleError> {
658        locked(&self.shared, |store, wake| {
659            store.settle(self.id, claim, outcome, wake)
660        })
661    }
662}
663
664/// Stores one `Claim` waker, whatever interface it was registered under, woken
665/// by a send of a member this handler serves, by a `serve` that admits a call
666/// already waiting, or by another handler's drop that returns a claim this
667/// handler serves.
668impl<E: Encoding> Wakeable for HandlerHandle<E> {
669    fn wake_on(&self, what: Interest, waker: &Waker) {
670        match what {
671            Interest::Claim(_) => locked(&self.shared, |store, wake| {
672                store.wait_claim(self.id, what, waker, wake);
673            }),
674            Interest::Outcome(_) | Interest::Slot | Interest::Event(_) => wake_at_once(waker),
675        }
676    }
677}