Repository: dotnet/aspnetcore
File: src/Servers/HttpSys/src/MessagePump.cs (C#)

Code before:
    private async Task StopAsyncCore()
    {
        // Shutdown the request queue to cancel pending accept operations.
        // This will cause the accept loops to wake up with an error and exit.
        Listener.RequestQueue.StopProcessingRequests();

        // Wait for accept loops to complete before disposing the listener.
        // This prevents a race where the BoundHandle is disposed while
        // AsyncAcceptContext is still trying to use it for cleanup.
        // After this completes, DecrementOutstandingRequest can signal _requestsDrained
        // (it checks _acceptLoopCount).
        await _acceptLoopsCompleted.Task.ConfigureAwait(false);

        // Signal request drain completion if no requests are outstanding,
        // otherwise the last request to complete will signal it.
        // Important to do this after accept loops complete to avoid hanging until cancellation
        if (Interlocked.CompareExchange(ref _outstandingRequests, 0, 0) == 0)
        {
            _requestsDrained.TrySetResult();
        }
        else
        {
            Log.WaitingForRequestsToDrain(_logger, _outstandingRequests);
        }

        await _requestsDrained.Task.ConfigureAwait(false);

        Listener.Dispose();
    }

    public DelegationRule CreateDelegationRule(string queueName, string uri)
    {
        var rule = new DelegationRule(Listener.UrlGroup, queueName, uri, _logger);
        Listener.UrlGroup.SetDelegationProperty(rule.Queue);
        return rule;
    }

    // Ungraceful shutdown
    public void Dispose()
    {
        StopAsync(new CancellationToken(canceled: true)).GetAwaiter().GetResult();
    }

    private void AcceptLoopCompleted()
    {
        lock (_shutdownLock)
        {
            if (--_acceptLoopCount == 0)
            {
                _acceptLoopsCompleted.TrySetResult();
            }

Review comment (suggestion):
Nit: Completing _requestsDrained just to await it is needlessly complicated. This is the only place we ever await _requestDrained and I think it's perfectly fine if it never completes when we don't need to await it.


```suggestion
        if (Interlocked.CompareExchange(ref _outstandingRequests, 0, 0) != 0)
        {
            Log.WaitingForRequestsToDrain(_logger, _outstandingRequests);
            await _requestsDrained.Task.ConfigureAwait(false);
        }
```

The diff is being weird, but the idea is that lines 247-259 could be replaced with just:

```csharp
        if (Interlocked.CompareExchange(ref _outstandingRequests, 0, 0) != 0)
        {
            Log.WaitingForRequestsToDrain(_logger, _outstandingRequests);
            await _requestsDrained.Task.ConfigureAwait(false);
        }
```

Code after:
    private async Task StopAsyncCore()
    {
        // Shutdown the request queue to cancel pending accept operations.
        // This will cause the accept loops to wake up with an error and exit.
        Listener.RequestQueue.StopProcessingRequests();

        // Wait for accept loops to complete before disposing the listener.
        // This prevents a race where the BoundHandle is disposed while
        // AsyncAcceptContext is still trying to use it for cleanup.
        // After this completes, DecrementOutstandingRequest can signal _requestsDrained
        // (it checks _acceptLoopCount).
        await _acceptLoopsCompleted.Task.ConfigureAwait(false);

        if (Interlocked.CompareExchange(ref _outstandingRequests, 0, 0) != 0)
        {
            Log.WaitingForRequestsToDrain(_logger, _outstandingRequests);
            await _requestsDrained.Task.ConfigureAwait(false);
        }

        Listener.Dispose();
    }

    public DelegationRule CreateDelegationRule(string queueName, string uri)
    {
        var rule = new DelegationRule(Listener.UrlGroup, queueName, uri, _logger);
        Listener.UrlGroup.SetDelegationProperty(rule.Queue);
        return rule;
    }

    // Ungraceful shutdown
    public void Dispose()
    {
        StopAsync(new CancellationToken(canceled: true)).GetAwaiter().GetResult();
    }

    private void AcceptLoopCompleted()
    {
        lock (_shutdownLock)
        {
            if (--_acceptLoopCount == 0)
            {
                _acceptLoopsCompleted.TrySetResult();
            }
        }
    }

    private sealed class AcceptLoop : IThreadPoolWorkItem
    {
        private readonly AsyncAcceptContext _asyncAcceptContext;
        private readonly MessagePump _messagePump;
        private readonly bool _preferInlineScheduling;