Repository: tokio-rs/tokio
File: tokio/src/sync/notify.rs (Rust)

Code before:
/// Notification for a `Waiter`.
/// This struct is equivalent to `Option<Notification>`, but uses
/// `AtomicUsize` inside for atomic operations.
#[derive(Debug)]
struct AtomicNotification(AtomicUsize);

impl AtomicNotification {
    fn none() -> Self {
        AtomicNotification(AtomicUsize::new(0))
    }

    /// Store-release a notification.
    /// This method should be called exactly once.
    fn store_release(&self, notification: Notification, strategy: Option<NotifyOneStrategy>) {
        let data: usize = match strategy {
            None => notification as usize & NOTIFICATION_TYPE_MASK,
            Some(strategy) => {
                (((strategy as usize) << NOTIFICATION_NOTIFY_ONE_STRATEGY_SHIFT)
                    & NOTIFICATION_NOTIFY_ONE_STRATEGY_MASK)
                    | (notification as usize & NOTIFICATION_TYPE_MASK)
            }
        };
        self.0.store(data, Release);
    }

    fn load(&self, ordering: Ordering) -> (Option<Notification>, Option<NotifyOneStrategy>) {
        let data = self.0.load(ordering);
        let notification = match data & NOTIFICATION_TYPE_MASK {
            NOTIFICATION_NONE => None,
            NOTIFICATION_ONE => Some(Notification::One),
            NOTIFICATION_ALL => Some(Notification::All),
            _ => unreachable!(),
        };
        let strategy = match (data & NOTIFICATION_NOTIFY_ONE_STRATEGY_MASK)
            >> NOTIFICATION_NOTIFY_ONE_STRATEGY_SHIFT
        {
            NOTIFICATION_NOTIFY_ONE_STRATEGY_NONE => None,
            NOTIFICATION_NOTIFY_ONE_STRATEGY_FIFO => Some(NotifyOneStrategy::Fifo),
            NOTIFICATION_NOTIFY_ONE_STRATEGY_LIFO => Some(NotifyOneStrategy::Lifo),
            _ => unreachable!(),
        };
        (notification, strategy)
    }

    /// Clears the notification.
    /// This method is used by a `Notified` future to consume the
    /// notification. It uses relaxed ordering and should be only
    /// used once the atomic notification is no longer shared.
    fn clear(&self) {
        self.0.store(0, Relaxed);
    }

Review comment (suggestion):
Is there ever a time when this will return `None` for `Notification` but will return `Some` for `NotifyOneStrategy`? I don't think there is. Perhaps, `Notification` the enum should take the strategy as an argument:

```rust
enum Notification {
    One(Strategy),
    All,
}
```

Code after:

    /// Store-release a notification.
    /// This method should be called exactly once.
    fn store_release(&self, notification: Notification) {
        let data: usize = match notification {
            Notification::All => NOTIFICATION_ALL,
            Notification::One(NotifyOneStrategy::Fifo) => NOTIFICATION_ONE,
            Notification::One(NotifyOneStrategy::Lifo) => NOTIFICATION_LAST,
        };
        self.0.store(data, Release);
    }

    fn load(&self, ordering: Ordering) -> Option<Notification> {
        let data = self.0.load(ordering);
        match data {
            NOTIFICATION_NONE => None,
            NOTIFICATION_ONE => Some(Notification::One(NotifyOneStrategy::Fifo)),
            NOTIFICATION_LAST => Some(Notification::One(NotifyOneStrategy::Lifo)),
            NOTIFICATION_ALL => Some(Notification::All),
            _ => unreachable!(),
        }
    }

    /// Clears the notification.
    /// This method is used by a `Notified` future to consume the
    /// notification. It uses relaxed ordering and should be only
    /// used once the atomic notification is no longer shared.
    fn clear(&self) {
        self.0.store(NOTIFICATION_NONE, Relaxed);
    }
}

#[derive(Debug, PartialEq, Eq)]
#[repr(usize)]
enum NotifyOneStrategy {
    Fifo,
    Lifo,
}

#[derive(Debug, PartialEq, Eq)]
#[repr(usize)]
enum Notification {
    One(NotifyOneStrategy),
    All,
}

/// List used in `Notify::notify_waiters`. It wraps a guarded linked list
/// and gates the access to it on `notify.waiters` mutex. It also empties
/// the list on drop.
struct NotifyWaitersList<'a> {
    list: GuardedWaitList,