unsafe fn try_acquire(
        &mut self,
        wait_node: &mut ListNode<WaitQueueEntry>,
        cx: &mut Context<'_>,
    ) -> Poll<()> {
        match wait_node.state {
            PollState::New => {
                // The fast path - enough permits are available
                if self.try_acquire_sync(wait_node.required_permits) {
                    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 SemaphoreAcquireFuture 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, check immediately
                    // if enough permits are available
                    if self.permits >= wait_node.required_permits {
                        self.permits -= wait_node.required_permits;
                        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 semaphore, since the semaphore is available again.
                // The semaphore thereby removed us from the waiters list.
                // Just try to lock again. If the semaphore isn't available,
                // we need to add it to the wait queue again.
                if self.permits >= wait_node.required_permits {
                    if self.is_fair {
                        // In a fair Semaphore, 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.permits -= wait_node.required_permits;
                    if self.is_fair {
                        // There might be another task which is ready to run,
                        // but couldn't, since it was blocked behind the fair waiter.
                        self.wakeup_waiters();
                    }
                    wait_node.state = PollState::Done;
                    Poll::Ready(())
                } else {
                    // A fair semaphore should never end up in that branch, since
                    // it's only notified when it's permits are guaranteed to
                    // be available. assert! in order to find logic bugs
                    assert!(
                        !self.is_fair,
                        "Fair semaphores should always be ready when notified"
                    );
                    // 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");
            }
        }
    }
/// Tries to acquire the Semaphore from a WaitQueueEntry.
/// If it isn't available, the WaitQueueEntry gets added to the wait
/// queue at the Semaphore, 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 Semaphore from a WaitQueueEntry.
If it isn't available, the WaitQueueEntry gets added to the wait
queue at the Semaphore, 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 Semaphore from a WaitQueueEntry . If it isn ' t available the WaitQueueEntry gets added to the wait queue at the Semaphore 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_acquire(
        &mut self,
        wait_node: &mut ListNode<WaitQueueEntry>,
        cx: &mut Context<'_>,
    ) -> Poll<()> {
        match wait_node.state {
            PollState::New => {
                // The fast path - enough permits are available
                if self.try_acquire_sync(wait_node.required_permits) {
                    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 SemaphoreAcquireFuture 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, check immediately
                    // if enough permits are available
                    if self.permits >= wait_node.required_permits {
                        self.permits -= wait_node.required_permits;
                        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 semaphore, since the semaphore is available again.
                // The semaphore thereby removed us from the waiters list.
                // Just try to lock again. If the semaphore isn't available,
                // we need to add it to the wait queue again.
                if self.permits >= wait_node.required_permits {
                    if self.is_fair {
                        // In a fair Semaphore, 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.permits -= wait_node.required_permits;
                    if self.is_fair {
                        // There might be another task which is ready to run,
                        // but couldn't, since it was blocked behind the fair waiter.
                        self.wakeup_waiters();
                    }
                    wait_node.state = PollState::Done;
                    Poll::Ready(())
                } else {
                    // A fair semaphore should never end up in that branch, since
                    // it's only notified when it's permits are guaranteed to
                    // be available. assert! in order to find logic bugs
                    assert!(
                        !self.is_fair,
                        "Fair semaphores should always be ready when notified"
                    );
                    // 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_acquire ( & mut self , wait_node : & mut ListNode < WaitQueueEntry > , cx : & mut Context < ' _ > , ) -> Poll < ( ) > { match wait_node . state { PollState :: New => { // The fast path - enough permits are available if self . try_acquire_sync ( wait_node . required_permits ) { 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 SemaphoreAcquireFuture 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, check immediately // if enough permits are available if self . permits >= wait_node . required_permits { self . permits -= wait_node . required_permits ; 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 semaphore, since the semaphore is available again. // The semaphore thereby removed us from the waiters list. // Just try to lock again. If the semaphore isn't available, // we need to add it to the wait queue again. if self . permits >= wait_node . required_permits { if self . is_fair { // In a fair Semaphore, 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 . permits -= wait_node . required_permits ; if self . is_fair { // There might be another task which is ready to run, // but couldn't, since it was blocked behind the fair waiter. self . wakeup_waiters ( ) ; } wait_node . state = PollState :: Done ; Poll :: Ready ( ( ) ) } else { // A fair semaphore should never end up in that branch, since // it's only notified when it's permits are guaranteed to // be available. assert! in order to find logic bugs 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 Semaphore from a WaitQueueEntry.
Tries to acquire the Semaphore from a WaitQueueEntry .
&mut self
wait_node
&mut ListNode<WaitQueueEntry>
cx
&mut Context<'_>
&mut self
wait_node
&mut ListNode<WaitQueueEntry>
cx
&mut Context<'_>