summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-12-26 14:12:00 -0500
committerBen Gamari <ben@smart-cactus.org>2020-12-27 11:24:26 -0500
commit458291fa7203b2ea7ff64281f356eea241b449cf (patch)
tree8012ae7fee010ec9e96e3b3e139a198981788079
parenta193728e20cd44d4d33952d3d267d382f5bdf90c (diff)
downloadhaskell-458291fa7203b2ea7ff64281f356eea241b449cf.tar.gz
keepAlive documentation
-rw-r--r--docs/users_guide/9.0.1-notes.rst17
-rw-r--r--libraries/base/GHC/ForeignPtr.hs33
-rw-r--r--libraries/base/changelog.md9
-rw-r--r--libraries/ghc-prim/changelog.md4
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