summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/ForeignPtr.hs
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/base/GHC/ForeignPtr.hs')
-rw-r--r--libraries/base/GHC/ForeignPtr.hs33
1 files changed, 20 insertions, 13 deletions
diff --git a/libraries/base/GHC/ForeignPtr.hs b/libraries/base/GHC/ForeignPtr.hs
index 6cc55221f4..79d1614529 100644
--- a/libraries/base/GHC/ForeignPtr.hs
+++ b/libraries/base/GHC/ForeignPtr.hs
@@ -533,7 +533,13 @@ withForeignPtr = unsafeWithForeignPtr
-- 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)
@@ -543,18 +549,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