From 610ed2107691d326c34d486ae1776fa69ed6354a Mon Sep 17 00:00:00 2001 From: Jakub Majocha <1760221+majocha@users.noreply.github.com> Date: Thu, 24 Oct 2024 21:20:46 +0200 Subject: [PATCH 1/3] nullify disposed waithandle --- src/FSharp.Core/mailbox.fs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/FSharp.Core/mailbox.fs b/src/FSharp.Core/mailbox.fs index a938263a05b..a6fdd418e26 100644 --- a/src/FSharp.Core/mailbox.fs +++ b/src/FSharp.Core/mailbox.fs @@ -340,10 +340,11 @@ type Mailbox<'Msg>(cancellationSupported: bool, isThrowExceptionAfterDisposed: b inboxStore.Clear() arrivals.Clear() - isDisposed <- true) + isDisposed <- true - if isNotNull pulse then - (pulse :> IDisposable).Dispose() + if isNotNull pulse then + (pulse :> IDisposable).Dispose() + pulse <- null) #if DEBUG member x.UnsafeContents = (x.inbox, arrivals, pulse, savedCont) |> box From a11d7049346fa8ce8760e7a3f3d8859ca0417bd2 Mon Sep 17 00:00:00 2001 From: Jakub Majocha <1760221+majocha@users.noreply.github.com> Date: Tue, 29 Oct 2024 20:17:43 +0100 Subject: [PATCH 2/3] add test --- .../MailboxProcessorType.fs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs index f3964aaa78c..1e2fcd58545 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs @@ -557,3 +557,42 @@ module MailboxProcessorType = } Assert.True(iteration.Result > 1, "TryScan did not timeout") + + let ordered() = + let mutable current = 1 + fun n -> + if n < current then failwith $"step {n} already happened" + SpinWait.SpinUntil(fun () -> n = current) + current <- n + 1 + + // See https://github.com/dotnet/fsharp/issues/17849 + [] + let ``Disposed MailboxProcessor does not throw on Post`` () = + task { + let step = ordered() + + let cts = new CancellationTokenSource() + let mb = + MailboxProcessor.Start( (fun inbox -> + async { + step 1 + do! inbox.Receive() + do! inbox.Receive() + return () + }), + cancellationToken = cts.Token + ) + + step 2 + // ensure pulse gets created + do! Task.Delay 100 + mb.Post() + + mb.Dispose() + + do! Task.Delay 100 + + mb.Post() + + cts.Cancel() + } From facd706f14ed3eadc21e1c3ed8adce1541f785b4 Mon Sep 17 00:00:00 2001 From: Jakub Majocha <1760221+majocha@users.noreply.github.com> Date: Tue, 29 Oct 2024 20:23:07 +0100 Subject: [PATCH 3/3] rns --- docs/release-notes/.FSharp.Core/9.0.200.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 docs/release-notes/.FSharp.Core/9.0.200.md diff --git a/docs/release-notes/.FSharp.Core/9.0.200.md b/docs/release-notes/.FSharp.Core/9.0.200.md new file mode 100644 index 00000000000..075290e821a --- /dev/null +++ b/docs/release-notes/.FSharp.Core/9.0.200.md @@ -0,0 +1,9 @@ +### Fixed + +* Fix exception on Post after MailboxProcessor was disposed ([Issue #17849](https://github.com/dotnet/fsharp/issues/17849), [PR #17922](https://github.com/dotnet/fsharp/pull/17922)) + +### Added + +### Changed + +### Breaking Changes \ No newline at end of file