/// Tries to acquire the Mutex from a WaitQueueEntry.
///
/// If it isn't available, the WaitQueueEntry gets added to the wait
/// queue at the Mutex, and will be signalled once ready.
/// This function is only safe as long as the `wait_node`s address is guaranteed
/// to be stable until it gets removed from the queue.
Tries to acquire the Mutex from a WaitQueueEntry.
If it isn't available, the WaitQueueEntry gets added to the wait
queue at the Mutex, and will be signalled once ready.
This function is only safe as long as the `wait_node`s address is guaranteed
to be stable until it gets removed from the queue.
Tries to acquire the Mutex from a WaitQueueEntry . If it isn ' t available the WaitQueueEntry gets added to the wait queue at the Mutex and will be signalled once ready . This function is only safe as long as the ` wait_node ` s address is guaranteed to be stable until it gets removed from the queue .
unsafe fn try_lock(
        &mut self,
        wait_node: &mut ListNode<WaitQueueEntry>,
        cx: &mut Context<'_>,
    ) -> Poll<()> {
        match wait_node.state {
            PollState::New => {
                // The fast path - the Mutex isn't locked by anyone else.
                // If the mutex is fair, noone must be in the wait list before us.
                if self.try_lock_sync() {
                    wait_node.state = PollState::Done;
                    Poll::Ready(())
                } else {
                    // Add the task to the wait queue
                    wait_node.task = Some(cx.waker().clone());
                    wait_node.state = PollState::Waiting;
                    self.waiters.add_front(wait_node);
                    Poll::Pending
                }
            }
            PollState::Waiting => {
                // The MutexLockFuture is already in the queue.
                if self.is_fair {
                    // The task needs to wait until it gets notified in order to
                    // maintain the ordering. However the caller might have
                    // passed a different `Waker`. In this case we need to update it.
                    update_waker_ref(&mut wait_node.task, cx);
                    Poll::Pending
                } else {
                    // For throughput improvement purposes, grab the lock immediately
                    // if it's available.
                    if !self.is_locked {
                        self.is_locked = true;
                        wait_node.state = PollState::Done;
                        // Since this waiter has been registered before, it must
                        // get removed from the waiter list.
                        // Safety: Due to the state, we know that the node must be part
                        // of the waiter list
                        self.force_remove_waiter(wait_node);
                        Poll::Ready(())
                    } else {
                        // The caller might have passed a different `Waker`.
                        // In this case we need to update it.
                        update_waker_ref(&mut wait_node.task, cx);
                        Poll::Pending
                    }
                }
            }
            PollState::Notified => {
                // We had been woken by the mutex, since the mutex is available again.
                // The mutex thereby removed us from the waiters list.
                // Just try to lock again. If the mutex isn't available,
                // we need to add it to the wait queue again.
                if !self.is_locked {
                    if self.is_fair {
                        // In a fair Mutex, the WaitQueueEntry is kept in the
                        // linked list and must be removed here
                        // Safety: Due to the state, we know that the node must be part
                        // of the waiter list
                        self.force_remove_waiter(wait_node);
                    }
                    self.is_locked = true;
                    wait_node.state = PollState::Done;
                    Poll::Ready(())
                } else {
                    // Fair mutexes should always be able to acquire the lock
                    // after they had been notified
                    debug_assert!(!self.is_fair);
                    // Add to queue
                    wait_node.task = Some(cx.waker().clone());
                    wait_node.state = PollState::Waiting;
                    self.waiters.add_front(wait_node);
                    Poll::Pending
                }
            }
            PollState::Done => {
                // The future had been polled to completion before
                panic!("polled Mutex after completion");
            }
        }
    }
unsafe fn try_lock ( & mut self , wait_node : & mut ListNode < WaitQueueEntry > , cx : & mut Context < ' _ > , ) -> Poll < ( ) > { match wait_node . state { PollState :: New => { // The fast path - the Mutex isn't locked by anyone else. // If the mutex is fair, noone must be in the wait list before us. if self . try_lock_sync ( ) { wait_node . state = PollState :: Done ; Poll :: Ready ( ( ) ) } else { // Add the task to the wait queue wait_node . task = Some ( cx . waker ( ) . clone ( ) ) ; wait_node . state = PollState :: Waiting ; self . waiters . add_front ( wait_node ) ; Poll :: Pending } } PollState :: Waiting => { // The MutexLockFuture is already in the queue. if self . is_fair { // The task needs to wait until it gets notified in order to // maintain the ordering. However the caller might have // passed a different `Waker`. In this case we need to update it. update_waker_ref ( & mut wait_node . task , cx ) ; Poll :: Pending } else { // For throughput improvement purposes, grab the lock immediately // if it's available. if ! self . is_locked { self . is_locked = true ; wait_node . state = PollState :: Done ; // Since this waiter has been registered before, it must // get removed from the waiter list. // Safety: Due to the state, we know that the node must be part // of the waiter list self . force_remove_waiter ( wait_node ) ; Poll :: Ready ( ( ) ) } else { // The caller might have passed a different `Waker`. // In this case we need to update it. update_waker_ref ( & mut wait_node . task , cx ) ; Poll :: Pending } } } PollState :: Notified => { // We had been woken by the mutex, since the mutex is available again. // The mutex thereby removed us from the waiters list. // Just try to lock again. If the mutex isn't available, // we need to add it to the wait queue again. if ! self . is_locked { if self . is_fair { // In a fair Mutex, the WaitQueueEntry is kept in the // linked list and must be removed here // Safety: Due to the state, we know that the node must be part // of the waiter list self . force_remove_waiter ( wait_node ) ; } self . is_locked = true ; wait_node . state = PollState :: Done ; Poll :: Ready ( ( ) ) } else { // Fair mutexes should always be able to acquire the lock // after they had been notified debug_assert ! ( self is_fair ) ; // Add to queue wait_node . task = Some ( cx . waker ( ) . clone ( ) ) ; wait_node . state = PollState :: Waiting ; self . waiters . add_front ( wait_node ) ; Poll :: Pending } } PollState :: Done => { // The future had been polled to completion before panic ! ( " " ) ; } } }
Tries to acquire the Mutex from a WaitQueueEntry.
Tries to acquire the Mutex from a WaitQueueEntry .
&mut self
wait_node
&mut ListNode<WaitQueueEntry>
cx
&mut Context<'_>