Skip to content

Commit 5f67dd0

Browse files
committed
Adjust the Notification logic slightly
I missed that this is needed for notification propogation.
1 parent d986a5c commit 5f67dd0

File tree

1 file changed

+88
-33
lines changed

1 file changed

+88
-33
lines changed

src/notify.rs

Lines changed: 88 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ pub trait Notification {
88
/// The tag data associated with a notification.
99
type Tag;
1010

11-
/// Emit a fence to ensure that the notification is visible to the
12-
/// listeners.
11+
/// Emit a fence to ensure that the notification is visible to the listeners.
1312
fn fence(&self);
1413

15-
/// Get the number of listeners to wake, given the number of listeners
16-
/// that are currently waiting.
17-
fn count(&self, waiting: usize) -> usize;
14+
/// Whether or not the number of currently waiting listeners should be subtracted from `count()`.
15+
fn is_additional(&self) -> bool;
16+
17+
/// Get the number of listeners to wake.
18+
fn count(&self) -> usize;
1819

1920
/// Get a tag to be associated with a notification.
2021
///
@@ -42,46 +43,53 @@ impl From<usize> for Notify {
4243
impl Notification for Notify {
4344
type Tag = ();
4445

46+
fn is_additional(&self) -> bool {
47+
false
48+
}
49+
4550
fn fence(&self) {
4651
full_fence();
4752
}
4853

49-
fn count(&self, waiting: usize) -> usize {
50-
self.0.saturating_sub(waiting)
54+
fn count(&self) -> usize {
55+
self.0
5156
}
5257

5358
fn next_tag(&mut self) -> Self::Tag {}
5459
}
5560

56-
/// Notify a given number of listeners.
61+
/// Make the underlying notification additional.
5762
#[derive(Debug, Clone)]
58-
pub struct NotifyAdditional(usize);
63+
pub struct Additional<N: ?Sized>(N);
5964

60-
impl NotifyAdditional {
61-
/// Create a new `NotifyAdditional` with the given number of listeners to notify.
62-
fn new(count: usize) -> Self {
63-
Self(count)
65+
impl<N> Additional<N> {
66+
/// Create a new `Additional` with the given notification.
67+
fn new(inner: N) -> Self {
68+
Self(inner)
6469
}
6570
}
6671

67-
impl From<usize> for NotifyAdditional {
68-
fn from(count: usize) -> Self {
69-
Self::new(count)
70-
}
71-
}
72+
impl<N> Notification for Additional<N>
73+
where
74+
N: Notification + ?Sized,
75+
{
76+
type Tag = N::Tag;
7277

73-
impl Notification for NotifyAdditional {
74-
type Tag = ();
78+
fn is_additional(&self) -> bool {
79+
true
80+
}
7581

7682
fn fence(&self) {
77-
full_fence();
83+
self.0.fence();
7884
}
7985

80-
fn count(&self, _waiting: usize) -> usize {
81-
self.0
86+
fn count(&self) -> usize {
87+
self.0.count()
8288
}
8389

84-
fn next_tag(&mut self) -> Self::Tag {}
90+
fn next_tag(&mut self) -> Self::Tag {
91+
self.0.next_tag()
92+
}
8593
}
8694

8795
/// Don't emit a fence for this notification.
@@ -101,12 +109,16 @@ where
101109
{
102110
type Tag = N::Tag;
103111

112+
fn is_additional(&self) -> bool {
113+
self.0.is_additional()
114+
}
115+
104116
fn fence(&self) {
105117
// Don't emit a fence.
106118
}
107119

108-
fn count(&self, waiting: usize) -> usize {
109-
self.0.count(waiting)
120+
fn count(&self) -> usize {
121+
self.0.count()
110122
}
111123

112124
fn next_tag(&mut self) -> Self::Tag {
@@ -138,12 +150,16 @@ where
138150
{
139151
type Tag = T;
140152

153+
fn is_additional(&self) -> bool {
154+
self.inner.is_additional()
155+
}
156+
141157
fn fence(&self) {
142158
self.inner.fence();
143159
}
144160

145-
fn count(&self, waiting: usize) -> usize {
146-
self.inner.count(waiting)
161+
fn count(&self) -> usize {
162+
self.inner.count()
147163
}
148164

149165
fn next_tag(&mut self) -> Self::Tag {
@@ -188,19 +204,58 @@ where
188204
{
189205
type Tag = T;
190206

207+
fn is_additional(&self) -> bool {
208+
self.inner.is_additional()
209+
}
210+
191211
fn fence(&self) {
192212
self.inner.fence();
193213
}
194214

195-
fn count(&self, waiting: usize) -> usize {
196-
self.inner.count(waiting)
215+
fn count(&self) -> usize {
216+
self.inner.count()
197217
}
198218

199219
fn next_tag(&mut self) -> Self::Tag {
200220
(self.tag)()
201221
}
202222
}
203223

224+
/// A single notification.
225+
pub(crate) struct SingleNotify<T> {
226+
additional: bool,
227+
tag: Option<T>,
228+
}
229+
230+
impl<T> SingleNotify<T> {
231+
pub(crate) fn new(additional: bool, tag: T) -> Self {
232+
Self {
233+
additional,
234+
tag: Some(tag),
235+
}
236+
}
237+
}
238+
239+
impl<T> Notification for SingleNotify<T> {
240+
type Tag = T;
241+
242+
fn is_additional(&self) -> bool {
243+
self.additional
244+
}
245+
246+
fn fence(&self) {
247+
// Don't emit a fence.
248+
}
249+
250+
fn count(&self) -> usize {
251+
1
252+
}
253+
254+
fn next_tag(&mut self) -> Self::Tag {
255+
self.tag.take().unwrap()
256+
}
257+
}
258+
204259
/// A value that can be converted into a [`Notification`].
205260
pub trait IntoNotification {
206261
/// The tag data associated with a notification.
@@ -213,11 +268,11 @@ pub trait IntoNotification {
213268
fn into_notification(self) -> Self::Notify;
214269

215270
/// Convert this value into an additional notification.
216-
fn additional(self) -> NotifyAdditional
271+
fn additional(self) -> Additional<Self::Notify>
217272
where
218-
Self: Sized + IntoNotification<Notify = Notify>,
273+
Self: Sized,
219274
{
220-
NotifyAdditional::new(self.into_notification().count(0))
275+
Additional::new(self.into_notification())
221276
}
222277

223278
/// Don't emit a fence for this notification.

0 commit comments

Comments
 (0)