Internal exception surfacing when calling `Post` on disposed `MailBoxProcessor` · Issue #17849 · dotnet/fsharp · GitHub
Skip to content

Internal exception surfacing when calling Post on disposed MailBoxProcessor #17849

Closed

Description

@majocha
Message: 
System.ObjectDisposedException : Cannot access a disposed object.
Object name: 'Microsoft.Win32.SafeHandles.SafeWaitHandle'.

  Stack Trace: 
SafeHandle.DangerousAddRef(Boolean& success)
Kernel32.SetEvent(SafeWaitHandle handle)
EventWaitHandle.Set()
Mailbox`1.Post(TMsg msg) line 193
FSharpMailboxProcessor`1.Post(TMsg message) line 419

I can see the above exception occasionally in this test:

I assume the expected behavior here is no exception?

I'll try to come up with consistent minimal repro, but the problem seems to be here:

match pulse with
| null -> () // no one waiting, leaving the message in the queue is sufficient
| ev ->
// someone is waiting on the wait handle
ev.Set() |> ignore

ev is disposed and Set will fail.

The fix seems to be to also assign null to pulse when disposing it here:

Activity

  1. added this to the Backlog milestone on Oct 8, 2024
  2. majocha commented on Oct 8, 2024

    @majocha
    ContributorAuthor

    This happens with timeouts or cancellation enabled, only then a wait handle is used in Mailbox.

  3. majocha commented on Oct 8, 2024

    @majocha
    ContributorAuthor

    Minimal repro:

    open System.Threading
    
    let cts = new CancellationTokenSource()
    let mb =
        MailboxProcessor.Start( (fun inbox ->
            async {
                let! _ = inbox.Receive()
                let! _ = inbox.Receive()
                return ()
            }),
            cancellationToken = cts.Token
        )
    
    // ensure pulse gets created
    Thread.Sleep 100
    
    mb.Post 1
    mb.Dispose()
    mb.Post 2
  4. T-Gro commented on Oct 14, 2024

    @T-Gro
    Member

    I think getting an ObjectDisposedException is the right scenario if the object was disposed.
    But it should be better controlled by Fsharp.Core and not thrown from internal usage.

  5. added
    Impact-Low(Internal MS Team use only) Describes an issue with limited impact on existing code.
    Area-LibraryIssues for FSharp.Core not covered elsewhere
    Area-Diagnosticsmistakes and possible improvements to diagnostics
    and removed
    Area-LibraryIssues for FSharp.Core not covered elsewhere
    on Oct 21, 2024
  6. majocha commented on Oct 24, 2024

    @majocha
    ContributorAuthor

    Related to https://github.com/dotnet/fsharp/pull/13036/files#diff-89da65b208fb5d835cded7993284e2c562b2d6530cc320cc030f5079dfc0372b possibly?

    I think the exception happens in a code path that was there before that PR.

    I think getting an ObjectDisposedException is the right scenario if the object was disposed. But it should be better controlled by Fsharp.Core and not thrown from internal usage.

    This may be a breaking change. It seems the current standard behavior most of the time is waiting indefinitely on a disposed wait handle. Only on rare occasions where the wait handle is disposed while it's not awaited this here bug happens.

  7. added a commit that references this issue on Oct 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-Diagnosticsmistakes and possible improvements to diagnosticsBugImpact-Low(Internal MS Team use only) Describes an issue with limited impact on existing code.

    Type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions