diff options
author | Ben Gamari <ben@smart-cactus.org> | 2020-12-26 14:12:00 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-12-27 11:24:26 -0500 |
commit | 458291fa7203b2ea7ff64281f356eea241b449cf (patch) | |
tree | 8012ae7fee010ec9e96e3b3e139a198981788079 | |
parent | a193728e20cd44d4d33952d3d267d382f5bdf90c (diff) | |
download | haskell-458291fa7203b2ea7ff64281f356eea241b449cf.tar.gz |
keepAlive documentation
-rw-r--r-- | docs/users_guide/9.0.1-notes.rst | 17 | ||||
-rw-r--r-- | libraries/base/GHC/ForeignPtr.hs | 33 | ||||
-rw-r--r-- | libraries/base/changelog.md | 9 | ||||
-rw-r--r-- | libraries/ghc-prim/changelog.md | 4 |
4 files changed, 50 insertions, 13 deletions
diff --git a/docs/users_guide/9.0.1-notes.rst b/docs/users_guide/9.0.1-notes.rst index d10be4ccf9..5e542496a2 100644 --- a/docs/users_guide/9.0.1-notes.rst +++ b/docs/users_guide/9.0.1-notes.rst @@ -351,12 +351,29 @@ Haddock -- | This comment used to trigger a parse error main = putStrLn "Hello" +``base`` library +~~~~~~~~~~~~~~~~ + +- ``Foreign.ForeignPtr.withForeignPtr`` is now less aggressively optimised, + avoiding the unsoundness issue reported in + :ghc-ticket:`17760` in exchange for a small amount of additional allocation. + + If your application is impacted significantly by this change and the + continuation given to ``withForeignPtr`` will not *provably* diverge (via + throwing of an exception or looping) then the previous optimisation behavior + can be recovered by instead using ``GHC.ForeignPtr.unsafeWithForeignPtr``. + + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ - Add a known-key ``cstringLength#`` to ``GHC.CString`` that is eligible for constant folding by a built-in rule. +- A new primop, ``keepAlive#``, has been introduced to replace ``touch#`` in + controlling object lifetime without the soundness issues affecting the latter + (see :ghc-ticket:`17760`) + ``ghc`` library ~~~~~~~~~~~~~~~ diff --git a/libraries/base/GHC/ForeignPtr.hs b/libraries/base/GHC/ForeignPtr.hs index c79bc7c172..02e820a929 100644 --- a/libraries/base/GHC/ForeignPtr.hs +++ b/libraries/base/GHC/ForeignPtr.hs @@ -536,7 +536,13 @@ withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s -> -- throw an exception). In exchange for this loss of generality, this function -- offers the ability of GHC to optimise more aggressively. -- --- See issue #17760 for the motivation for this function. +-- Specifically, applications of the form: +-- @ +-- unsafeWithForeignPtr fptr ('Control.Monad.forever' something) +-- @ +-- +-- See GHC issue #17760 for more information about the unsoundness behavior +-- that this function can result in. unsafeWithForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b unsafeWithForeignPtr fo f = do r <- f (unsafeForeignPtrToPtr fo) @@ -546,18 +552,19 @@ unsafeWithForeignPtr fo f = do touchForeignPtr :: ForeignPtr a -> IO () -- ^This function ensures that the foreign object in -- question is alive at the given place in the sequence of IO --- actions. In particular 'Foreign.ForeignPtr.withForeignPtr' --- does a 'touchForeignPtr' after it --- executes the user action. --- --- Note that this function should not be used to express dependencies --- between finalizers on 'ForeignPtr's. For example, if the finalizer --- for a 'ForeignPtr' @F1@ calls 'touchForeignPtr' on a second --- 'ForeignPtr' @F2@, then the only guarantee is that the finalizer --- for @F2@ is never started before the finalizer for @F1@. They --- might be started together if for example both @F1@ and @F2@ are --- otherwise unreachable, and in that case the scheduler might end up --- running the finalizer for @F2@ first. +-- actions. However, this comes with a significant caveat: the contract above +-- does not hold if GHC can demonstrate that the code preceeding +-- @touchForeignPtr@ diverges (e.g. by looping infinitely or throwing an +-- exception). For this reason, you are strongly advised to use instead +-- 'withForeignPtr' where possible. +-- +-- Also, note that this function should not be used to express dependencies +-- between finalizers on 'ForeignPtr's. For example, if the finalizer for a +-- 'ForeignPtr' @F1@ calls 'touchForeignPtr' on a second 'ForeignPtr' @F2@, +-- then the only guarantee is that the finalizer for @F2@ is never started +-- before the finalizer for @F1@. They might be started together if for +-- example both @F1@ and @F2@ are otherwise unreachable, and in that case the +-- scheduler might end up running the finalizer for @F2@ first. -- -- In general, it is not recommended to use finalizers on separate -- objects with ordering constraints between them. To express the diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md index 749448fa8a..7574cb9eaf 100644 --- a/libraries/base/changelog.md +++ b/libraries/base/changelog.md @@ -36,6 +36,15 @@ * Correct `Bounded` instance and remove `Enum` and `Integral` instances for `Data.Ord.Down`. + * `Foreign.ForeignPtr.withForeignPtr` is now less aggressively optimised, + avoiding the soundness issue reported in + [#17760](https://gitlab.haskell.org/ghc/ghc/-/issues/17760) in exchange for + a small amount more allocation. If your application regresses significantly + *and* the continuation given to `withForeignPtr` will *not* provably + diverge then the previous optimisation behavior can be recovered by instead + using `GHC.ForeignPtr.unsafeWithForeignPtr`. + + ## 4.14.0.0 *Jan 2020* * Bundled with GHC 8.10.1 diff --git a/libraries/ghc-prim/changelog.md b/libraries/ghc-prim/changelog.md index 4a3e9f640c..04504cbf28 100644 --- a/libraries/ghc-prim/changelog.md +++ b/libraries/ghc-prim/changelog.md @@ -33,6 +33,10 @@ infix 4 ~, ~~ +- Introduce `keepAlive#` to replace `touch#` in controlling object lifetime without + the soundness issues of the latter (see + [#17760](https://gitlab.haskell.org/ghc/ghc/-/issues/17760)). + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 |