{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE Unsafe #-}

{-# OPTIONS_HADDOCK not-home #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  GHC.ForeignPtr
-- Copyright   :  (c) The University of Glasgow, 1992-2003
-- License     :  see libraries/base/LICENSE
--
-- Maintainer  :  cvs-ghc@haskell.org
-- Stability   :  internal
-- Portability :  non-portable (GHC extensions)
--
-- GHC's implementation of the 'ForeignPtr' data type.
--
-----------------------------------------------------------------------------

module GHC.ForeignPtr
  (
        -- * Types
        ForeignPtr(..),
        ForeignPtrContents(..),
        Finalizers(..),
        FinalizerPtr,
        FinalizerEnvPtr,
        -- * Create
        newForeignPtr_,
        mallocForeignPtr,
        mallocPlainForeignPtr,
        mallocForeignPtrBytes,
        mallocPlainForeignPtrBytes,
        mallocForeignPtrAlignedBytes,
        mallocPlainForeignPtrAlignedBytes,
        newConcForeignPtr,
        -- * Add Finalizers
        addForeignPtrFinalizer,
        addForeignPtrFinalizerEnv,
        addForeignPtrConcFinalizer,
        -- * Conversion
        unsafeForeignPtrToPtr,
        castForeignPtr,
        plusForeignPtr,
        -- * Control over lifetype
        withForeignPtr,
        unsafeWithForeignPtr,
        touchForeignPtr,
        -- * Finalization
        finalizeForeignPtr
        -- * Commentary
        -- $commentary
  ) where

import Foreign.Storable
import Data.Foldable    ( sequence_ )

import GHC.Show
import GHC.Base
import GHC.IORef
import GHC.STRef        ( STRef(..) )
import GHC.Ptr          ( Ptr(..), FunPtr(..) )

import Unsafe.Coerce    ( unsafeCoerce )

-- |The type 'ForeignPtr' represents references to objects that are
-- maintained in a foreign language, i.e., that are not part of the
-- data structures usually managed by the Haskell storage manager.
-- The essential difference between 'ForeignPtr's and vanilla memory
-- references of type @Ptr a@ is that the former may be associated
-- with /finalizers/. A finalizer is a routine that is invoked when
-- the Haskell storage manager detects that - within the Haskell heap
-- and stack - there are no more references left that are pointing to
-- the 'ForeignPtr'.  Typically, the finalizer will, then, invoke
-- routines in the foreign language that free the resources bound by
-- the foreign object.
--
-- The 'ForeignPtr' is parameterised in the same way as 'Ptr'.  The
-- type argument of 'ForeignPtr' should normally be an instance of
-- class 'Storable'.
--
data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents
        -- The Addr# in the ForeignPtr object is intentionally stored
        -- separately from the finalizer. The primary aim of the
        -- representation is to make withForeignPtr efficient; in fact,
        -- withForeignPtr should be just as efficient as unpacking a
        -- Ptr, and multiple withForeignPtrs can share an unpacked
        -- ForeignPtr. As a secondary benefit, this representation
        -- allows pointers to subregions within the same overall block
        -- to share the same finalizer (see 'plusForeignPtr'). Note
        -- that touchForeignPtr only has to touch the ForeignPtrContents
        -- object, because that ensures that whatever the finalizer is
        -- attached to is kept alive.

-- | Functions called when a 'ForeignPtr' is finalized. Note that
-- C finalizers and Haskell finalizers cannot be mixed.
data Finalizers
  = NoFinalizers
    -- ^ No finalizer. If there is no intent to add a finalizer at
    -- any point in the future, consider 'FinalPtr' or 'PlainPtr' instead
    -- since these perform fewer allocations.
  | CFinalizers (Weak# ())
    -- ^ Finalizers are all C functions.
  | HaskellFinalizers [IO ()]
    -- ^ Finalizers are all Haskell functions.

-- | Controls finalization of a 'ForeignPtr', that is, what should happen
-- if the 'ForeignPtr' becomes unreachable. Visually, these data constructors
-- are appropriate in these scenarios:
--
-- >                           Memory backing pointer is
-- >                            GC-Managed   Unmanaged
-- > Finalizer functions are: +------------+-----------------+
-- >                 Allowed  | MallocPtr  | PlainForeignPtr |
-- >                          +------------+-----------------+
-- >              Prohibited  | PlainPtr   | FinalPtr        |
-- >                          +------------+-----------------+
data ForeignPtrContents
  = PlainForeignPtr !(IORef Finalizers)
    -- ^ The pointer refers to unmanaged memory that was allocated by
    -- a foreign function (typically using @malloc@). The finalizer
    -- frequently calls the C function @free@ or some variant of it.
  | FinalPtr
    -- ^ The pointer refers to unmanaged memory that should not be freed when
    -- the 'ForeignPtr' becomes unreachable. Functions that add finalizers
    -- to a 'ForeignPtr' throw exceptions when the 'ForeignPtr' is backed by
    -- 'PlainPtr'Most commonly, this is used with @Addr#@ literals.
    -- See Note [Why FinalPtr].
    --
    -- @since 4.15
  | MallocPtr (MutableByteArray# RealWorld) !(IORef Finalizers)
    -- ^ The pointer refers to a byte array.
    -- The 'MutableByteArray#' field means that the 'MutableByteArray#' is
    -- reachable (by GC) whenever the 'ForeignPtr' is reachable. When the
    -- 'ForeignPtr' becomes unreachable, the runtime\'s normal GC recovers
    -- the memory backing it. Here, the finalizer function intended to be used
    -- to @free()@ any ancillary *unmanaged* memory pointed to by the
    -- 'MutableByteArray#'. See the @zlib@ library for an example of this use.
    --
    -- 1. Invariant: The 'Addr#' in the parent 'ForeignPtr' is an interior
    --    pointer into this 'MutableByteArray#'.
    -- 2. Invariant: The 'MutableByteArray#' is pinned, so the 'Addr#' does not
    --    get invalidated by the GC moving the byte array.
    -- 3. Invariant: A 'MutableByteArray#' must not be associated with more than
    --    one set of finalizers. For example, this is sound:
    --
    --    > incrGood :: ForeignPtr Word8 -> ForeignPtr Word8
    --    > incrGood (ForeignPtr p (MallocPtr m f)) = ForeignPtr (plusPtr p 1) (MallocPtr m f)
    --
    --    But this is unsound:
    --
    --    > incrBad :: ForeignPtr Word8 -> IO (ForeignPtr Word8)
    --    > incrBad (ForeignPtr p (MallocPtr m _)) = do
    --    >   f <- newIORef NoFinalizers
    --    >   pure (ForeignPtr p (MallocPtr m f))
  | PlainPtr (MutableByteArray# RealWorld)
    -- ^ The pointer refers to a byte array. Finalization is not
    -- supported. This optimizes @MallocPtr@ by avoiding the allocation
    -- of a @MutVar#@ when it is known that no one will add finalizers to
    -- the @ForeignPtr@. Functions that add finalizers to a 'ForeignPtr'
    -- throw exceptions when the 'ForeignPtr' is backed by 'PlainPtr'.
    -- The invariants that apply to 'MallocPtr' apply to 'PlainPtr' as well.

-- Note [Why FinalPtr]
--
-- FinalPtr exists as an optimization for foreign pointers created
-- from Addr# literals. Most commonly, this happens in the bytestring
-- library, where the combination of OverloadedStrings and a rewrite
-- rule overloads String literals as ByteString literals. See the
-- rule "ByteString packChars/packAddress" in
-- bytestring:Data.ByteString.Internal. Prior to the
-- introduction of FinalPtr, bytestring used PlainForeignPtr (in
-- Data.ByteString.Internal.unsafePackAddress) to handle such literals.
-- With O2 optimization, the resulting Core from a GHC patched with a
-- known-key cstringLength# function but without FinalPtr looked like:
--
--   RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
--   stringOne1 = "hello beautiful world"#
--   RHS size: {terms: 11, types: 17, coercions: 0, joins: 0/0}
--   stringOne
--     = case newMutVar# NoFinalizers realWorld# of
--       { (# ipv_i7b6, ipv1_i7b7 #) ->
--       PS stringOne1 (PlainForeignPtr ipv1_i7b7) 0# 21#
--       }
--
-- After the introduction of FinalPtr, the bytestring library was modified
-- so that the resulting Core was instead:
--
--   RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
--   stringOne1 = "hello beautiful world"#
--   RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0}
--   stringOne = PS stringOne1 FinalPtr 0# 21#
--
-- This improves performance in three ways:
--
-- 1. More optimization opportunities. GHC is willing to inline the FinalPtr
--    variant of stringOne into its use sites. This means the offset and length
--    are eligible for case-of-known-literal. Previously, this never happened.
-- 2. Smaller binaries. Setting up the thunk to call newMutVar# required
--    machine instruction in the generated code. On x86_64, FinalPtr reduces
--    the size of binaries by about 450 bytes per ByteString literal.
-- 3. Smaller memory footprint. Previously, every ByteString literal resulted
--    in the allocation of a MutVar# and a PlainForeignPtr data constructor.
--    These both hang around until the ByteString goes out of scope. FinalPtr
--    eliminates both of these sources of allocations. The MutVar# is not
--    allocated because FinalPtr does not allow it, and the data constructor
--    is not allocated because FinalPtr is a nullary data constructor.
--
-- For more discussion of FinalPtr, see GHC MR #2165 and bytestring PR #191.

-- | @since 2.01
instance Eq (ForeignPtr a) where
    ForeignPtr a
p == :: ForeignPtr a -> ForeignPtr a -> Bool
== ForeignPtr a
q  =  ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
p Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
q

-- | @since 2.01
instance Ord (ForeignPtr a) where
    compare :: ForeignPtr a -> ForeignPtr a -> Ordering
compare ForeignPtr a
p ForeignPtr a
q  =  Ptr a -> Ptr a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
p) (ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
q)

-- | @since 2.01
instance Show (ForeignPtr a) where
    showsPrec :: Int -> ForeignPtr a -> ShowS
showsPrec Int
p ForeignPtr a
f = Int -> Ptr a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
p (ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
f)


-- |A finalizer is represented as a pointer to a foreign function that, at
-- finalisation time, gets as an argument a plain pointer variant of the
-- foreign pointer that the finalizer is associated with.
--
-- Note that the foreign function /must/ use the @ccall@ calling convention.
--
type FinalizerPtr a        = FunPtr (Ptr a -> IO ())
type FinalizerEnvPtr env a = FunPtr (Ptr env -> Ptr a -> IO ())

newConcForeignPtr :: Ptr a -> IO () -> IO (ForeignPtr a)
--
-- ^Turns a plain memory reference into a foreign object by
-- associating a finalizer - given by the monadic operation - with the
-- reference.  The storage manager will start the finalizer, in a
-- separate thread, some time after the last reference to the
-- @ForeignPtr@ is dropped.  There is no guarantee of promptness, and
-- in fact there is no guarantee that the finalizer will eventually
-- run at all.
--
-- Note that references from a finalizer do not necessarily prevent
-- another object from being finalized.  If A's finalizer refers to B
-- (perhaps using 'touchForeignPtr', then the only guarantee is that
-- B's finalizer will never be started before A's.  If both A and B
-- are unreachable, then both finalizers will start together.  See
-- 'touchForeignPtr' for more on finalizer ordering.
--
newConcForeignPtr :: forall a. Ptr a -> IO () -> IO (ForeignPtr a)
newConcForeignPtr Ptr a
p IO ()
finalizer
  = do ForeignPtr a
fObj <- Ptr a -> IO (ForeignPtr a)
forall a. Ptr a -> IO (ForeignPtr a)
newForeignPtr_ Ptr a
p
       ForeignPtr a -> IO () -> IO ()
forall a. ForeignPtr a -> IO () -> IO ()
addForeignPtrConcFinalizer ForeignPtr a
fObj IO ()
finalizer
       ForeignPtr a -> IO (ForeignPtr a)
forall (m :: * -> *) a. Monad m => a -> m a
return ForeignPtr a
fObj

mallocForeignPtr :: Storable a => IO (ForeignPtr a)
-- ^ Allocate some memory and return a 'ForeignPtr' to it.  The memory
-- will be released automatically when the 'ForeignPtr' is discarded.
--
-- 'mallocForeignPtr' is equivalent to
--
-- >    do { p <- malloc; newForeignPtr finalizerFree p }
--
-- although it may be implemented differently internally: you may not
-- assume that the memory returned by 'mallocForeignPtr' has been
-- allocated with 'Foreign.Marshal.Alloc.malloc'.
--
-- GHC notes: 'mallocForeignPtr' has a heavily optimised
-- implementation in GHC.  It uses pinned memory in the garbage
-- collected heap, so the 'ForeignPtr' does not require a finalizer to
-- free the memory.  Use of 'mallocForeignPtr' and associated
-- functions is strongly recommended in preference to
-- 'Foreign.ForeignPtr.newForeignPtr' with a finalizer.
--
mallocForeignPtr :: forall a. Storable a => IO (ForeignPtr a)
mallocForeignPtr = a -> IO (ForeignPtr a)
forall b. Storable b => b -> IO (ForeignPtr b)
doMalloc a
forall a. HasCallStack => a
undefined
  where doMalloc :: Storable b => b -> IO (ForeignPtr b)
        doMalloc :: forall b. Storable b => b -> IO (ForeignPtr b)
doMalloc b
a
          | Int# -> Int
I# Int#
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = String -> IO (ForeignPtr b)
forall a. String -> a
errorWithoutStackTrace String
"mallocForeignPtr: size must be >= 0"
          | Bool
otherwise = do
          IORef Finalizers
r <- Finalizers -> IO (IORef Finalizers)
forall a. a -> IO (IORef a)
newIORef Finalizers
NoFinalizers
          (State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
-> IO (ForeignPtr b)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
 -> IO (ForeignPtr b))
-> (State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
-> IO (ForeignPtr b)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
            case Int#
-> Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d.
Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
newAlignedPinnedByteArray# Int#
size Int#
align State# RealWorld
s of { (# State# RealWorld
s', MutableByteArray# RealWorld
mbarr# #) ->
             (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr b
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (MutableByteArray# RealWorld -> Addr#
forall d. MutableByteArray# d -> Addr#
mutableByteArrayContents# MutableByteArray# RealWorld
mbarr#)
                               (MutableByteArray# RealWorld
-> IORef Finalizers -> ForeignPtrContents
MallocPtr MutableByteArray# RealWorld
mbarr# IORef Finalizers
r) #)
            }
            where !(I# Int#
size)  = b -> Int
forall a. Storable a => a -> Int
sizeOf b
a
                  !(I# Int#
align) = b -> Int
forall a. Storable a => a -> Int
alignment b
a

-- | This function is similar to 'mallocForeignPtr', except that the
-- size of the memory required is given explicitly as a number of bytes.
mallocForeignPtrBytes :: Int -> IO (ForeignPtr a)
mallocForeignPtrBytes :: forall a. Int -> IO (ForeignPtr a)
mallocForeignPtrBytes Int
size | Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
  String -> IO (ForeignPtr a)
forall a. String -> a
errorWithoutStackTrace String
"mallocForeignPtrBytes: size must be >= 0"
mallocForeignPtrBytes (I# Int#
size) = do
  IORef Finalizers
r <- Finalizers -> IO (IORef Finalizers)
forall a. a -> IO (IORef a)
newIORef Finalizers
NoFinalizers
  (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
 -> IO (ForeignPtr a))
-> (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
     case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newPinnedByteArray# Int#
size State# RealWorld
s      of { (# State# RealWorld
s', MutableByteArray# RealWorld
mbarr# #) ->
       (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (MutableByteArray# RealWorld -> Addr#
forall d. MutableByteArray# d -> Addr#
mutableByteArrayContents# MutableByteArray# RealWorld
mbarr#)
                         (MutableByteArray# RealWorld
-> IORef Finalizers -> ForeignPtrContents
MallocPtr MutableByteArray# RealWorld
mbarr# IORef Finalizers
r) #)
     }

-- | This function is similar to 'mallocForeignPtrBytes', except that the
-- size and alignment of the memory required is given explicitly as numbers of
-- bytes.
mallocForeignPtrAlignedBytes :: Int -> Int -> IO (ForeignPtr a)
mallocForeignPtrAlignedBytes :: forall a. Int -> Int -> IO (ForeignPtr a)
mallocForeignPtrAlignedBytes Int
size Int
_align | Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
  String -> IO (ForeignPtr a)
forall a. String -> a
errorWithoutStackTrace String
"mallocForeignPtrAlignedBytes: size must be >= 0"
mallocForeignPtrAlignedBytes (I# Int#
size) (I# Int#
align) = do
  IORef Finalizers
r <- Finalizers -> IO (IORef Finalizers)
forall a. a -> IO (IORef a)
newIORef Finalizers
NoFinalizers
  (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
 -> IO (ForeignPtr a))
-> (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
     case Int#
-> Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d.
Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
newAlignedPinnedByteArray# Int#
size Int#
align State# RealWorld
s of { (# State# RealWorld
s', MutableByteArray# RealWorld
mbarr# #) ->
       (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (MutableByteArray# RealWorld -> Addr#
forall d. MutableByteArray# d -> Addr#
mutableByteArrayContents# MutableByteArray# RealWorld
mbarr#)
                         (MutableByteArray# RealWorld
-> IORef Finalizers -> ForeignPtrContents
MallocPtr MutableByteArray# RealWorld
mbarr# IORef Finalizers
r) #)
     }

-- | Allocate some memory and return a 'ForeignPtr' to it.  The memory
-- will be released automatically when the 'ForeignPtr' is discarded.
--
-- GHC notes: 'mallocPlainForeignPtr' has a heavily optimised
-- implementation in GHC.  It uses pinned memory in the garbage
-- collected heap, as for mallocForeignPtr. Unlike mallocForeignPtr, a
-- ForeignPtr created with mallocPlainForeignPtr carries no finalizers.
-- It is not possible to add a finalizer to a ForeignPtr created with
-- mallocPlainForeignPtr. This is useful for ForeignPtrs that will live
-- only inside Haskell (such as those created for packed strings).
-- Attempts to add a finalizer to a ForeignPtr created this way, or to
-- finalize such a pointer, will throw an exception.
--
mallocPlainForeignPtr :: Storable a => IO (ForeignPtr a)
mallocPlainForeignPtr :: forall a. Storable a => IO (ForeignPtr a)
mallocPlainForeignPtr = a -> IO (ForeignPtr a)
forall b. Storable b => b -> IO (ForeignPtr b)
doMalloc a
forall a. HasCallStack => a
undefined
  where doMalloc :: Storable b => b -> IO (ForeignPtr b)
        doMalloc :: forall b. Storable b => b -> IO (ForeignPtr b)
doMalloc b
a
          | Int# -> Int
I# Int#
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = String -> IO (ForeignPtr b)
forall a. String -> a
errorWithoutStackTrace String
"mallocForeignPtr: size must be >= 0"
          | Bool
otherwise = (State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
-> IO (ForeignPtr b)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
 -> IO (ForeignPtr b))
-> (State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
-> IO (ForeignPtr b)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
            case Int#
-> Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d.
Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
newAlignedPinnedByteArray# Int#
size Int#
align State# RealWorld
s of { (# State# RealWorld
s', MutableByteArray# RealWorld
mbarr# #) ->
             (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr b
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (MutableByteArray# RealWorld -> Addr#
forall d. MutableByteArray# d -> Addr#
mutableByteArrayContents# MutableByteArray# RealWorld
mbarr#)
                               (MutableByteArray# RealWorld -> ForeignPtrContents
PlainPtr MutableByteArray# RealWorld
mbarr#) #)
            }
            where !(I# Int#
size)  = b -> Int
forall a. Storable a => a -> Int
sizeOf b
a
                  !(I# Int#
align) = b -> Int
forall a. Storable a => a -> Int
alignment b
a

-- | This function is similar to 'mallocForeignPtrBytes', except that
-- the internally an optimised ForeignPtr representation with no
-- finalizer is used. Attempts to add a finalizer will cause an
-- exception to be thrown.
mallocPlainForeignPtrBytes :: Int -> IO (ForeignPtr a)
mallocPlainForeignPtrBytes :: forall a. Int -> IO (ForeignPtr a)
mallocPlainForeignPtrBytes Int
size | Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
  String -> IO (ForeignPtr a)
forall a. String -> a
errorWithoutStackTrace String
"mallocPlainForeignPtrBytes: size must be >= 0"
mallocPlainForeignPtrBytes (I# Int#
size) = (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
 -> IO (ForeignPtr a))
-> (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
    case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newPinnedByteArray# Int#
size State# RealWorld
s      of { (# State# RealWorld
s', MutableByteArray# RealWorld
mbarr# #) ->
       (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (MutableByteArray# RealWorld -> Addr#
forall d. MutableByteArray# d -> Addr#
mutableByteArrayContents# MutableByteArray# RealWorld
mbarr#)
                         (MutableByteArray# RealWorld -> ForeignPtrContents
PlainPtr MutableByteArray# RealWorld
mbarr#) #)
     }

-- | This function is similar to 'mallocForeignPtrAlignedBytes', except that
-- the internally an optimised ForeignPtr representation with no
-- finalizer is used. Attempts to add a finalizer will cause an
-- exception to be thrown.
mallocPlainForeignPtrAlignedBytes :: Int -> Int -> IO (ForeignPtr a)
mallocPlainForeignPtrAlignedBytes :: forall a. Int -> Int -> IO (ForeignPtr a)
mallocPlainForeignPtrAlignedBytes Int
size Int
_align | Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
  String -> IO (ForeignPtr a)
forall a. String -> a
errorWithoutStackTrace String
"mallocPlainForeignPtrAlignedBytes: size must be >= 0"
mallocPlainForeignPtrAlignedBytes (I# Int#
size) (I# Int#
align) = (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
 -> IO (ForeignPtr a))
-> (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
-> IO (ForeignPtr a)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
    case Int#
-> Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d.
Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
newAlignedPinnedByteArray# Int#
size Int#
align State# RealWorld
s of { (# State# RealWorld
s', MutableByteArray# RealWorld
mbarr# #) ->
       (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (MutableByteArray# RealWorld -> Addr#
forall d. MutableByteArray# d -> Addr#
mutableByteArrayContents# MutableByteArray# RealWorld
mbarr#)
                         (MutableByteArray# RealWorld -> ForeignPtrContents
PlainPtr MutableByteArray# RealWorld
mbarr#) #)
     }

addForeignPtrFinalizer :: FinalizerPtr a -> ForeignPtr a -> IO ()
-- ^ This function adds a finalizer to the given foreign object.  The
-- finalizer will run /before/ all other finalizers for the same
-- object which have already been registered.
addForeignPtrFinalizer :: forall a. FinalizerPtr a -> ForeignPtr a -> IO ()
addForeignPtrFinalizer (FunPtr Addr#
fp) (ForeignPtr Addr#
p ForeignPtrContents
c) = case ForeignPtrContents
c of
  PlainForeignPtr IORef Finalizers
r -> IORef Finalizers -> Addr# -> Int# -> Addr# -> Addr# -> () -> IO ()
forall value.
IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
insertCFinalizer IORef Finalizers
r Addr#
fp Int#
0# Addr#
nullAddr# Addr#
p ()
  MallocPtr     MutableByteArray# RealWorld
_ IORef Finalizers
r -> IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> ForeignPtrContents -> IO ()
forall value.
IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
insertCFinalizer IORef Finalizers
r Addr#
fp Int#
0# Addr#
nullAddr# Addr#
p ForeignPtrContents
c
  ForeignPtrContents
_ -> String -> IO ()
forall a. String -> a
errorWithoutStackTrace String
"GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer"

-- Note [MallocPtr finalizers] (#10904)
--
-- When we have C finalizers for a MallocPtr, the memory is
-- heap-resident and would normally be recovered by the GC before the
-- finalizers run.  To prevent the memory from being reused too early,
-- we attach the MallocPtr constructor to the "value" field of the
-- weak pointer when we call mkWeak# in ensureCFinalizerWeak below.
-- The GC will keep this field alive until the finalizers have run.

addForeignPtrFinalizerEnv ::
  FinalizerEnvPtr env a -> Ptr env -> ForeignPtr a -> IO ()
-- ^ Like 'addForeignPtrFinalizer' but the finalizer is passed an additional
-- environment parameter.
addForeignPtrFinalizerEnv :: forall env a.
FinalizerEnvPtr env a -> Ptr env -> ForeignPtr a -> IO ()
addForeignPtrFinalizerEnv (FunPtr Addr#
fp) (Ptr Addr#
ep) (ForeignPtr Addr#
p ForeignPtrContents
c) = case ForeignPtrContents
c of
  PlainForeignPtr IORef Finalizers
r -> IORef Finalizers -> Addr# -> Int# -> Addr# -> Addr# -> () -> IO ()
forall value.
IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
insertCFinalizer IORef Finalizers
r Addr#
fp Int#
1# Addr#
ep Addr#
p ()
  MallocPtr     MutableByteArray# RealWorld
_ IORef Finalizers
r -> IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> ForeignPtrContents -> IO ()
forall value.
IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
insertCFinalizer IORef Finalizers
r Addr#
fp Int#
1# Addr#
ep Addr#
p ForeignPtrContents
c
  ForeignPtrContents
_ -> String -> IO ()
forall a. String -> a
errorWithoutStackTrace String
"GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer"

addForeignPtrConcFinalizer :: ForeignPtr a -> IO () -> IO ()
-- ^This function adds a finalizer to the given @ForeignPtr@.  The
-- finalizer will run /before/ all other finalizers for the same
-- object which have already been registered.
--
-- This is a variant of @addForeignPtrFinalizer@, where the finalizer
-- is an arbitrary @IO@ action.  When it is invoked, the finalizer
-- will run in a new thread.
--
-- NB. Be very careful with these finalizers.  One common trap is that
-- if a finalizer references another finalized value, it does not
-- prevent that value from being finalized.  In particular, 'System.IO.Handle's
-- are finalized objects, so a finalizer should not refer to a
-- 'System.IO.Handle' (including 'System.IO.stdout', 'System.IO.stdin', or
-- 'System.IO.stderr').
--
addForeignPtrConcFinalizer :: forall a. ForeignPtr a -> IO () -> IO ()
addForeignPtrConcFinalizer (ForeignPtr Addr#
_ ForeignPtrContents
c) IO ()
finalizer =
  ForeignPtrContents -> IO () -> IO ()
addForeignPtrConcFinalizer_ ForeignPtrContents
c IO ()
finalizer

addForeignPtrConcFinalizer_ :: ForeignPtrContents -> IO () -> IO ()
addForeignPtrConcFinalizer_ :: ForeignPtrContents -> IO () -> IO ()
addForeignPtrConcFinalizer_ (PlainForeignPtr IORef Finalizers
r) IO ()
finalizer = do
  Bool
noFinalizers <- IORef Finalizers -> IO () -> IO Bool
insertHaskellFinalizer IORef Finalizers
r IO ()
finalizer
  if Bool
noFinalizers
     then (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
              case IORef Finalizers
r of { IORef (STRef MutVar# RealWorld Finalizers
r#) ->
              case MutVar# RealWorld Finalizers
-> ()
-> (State# RealWorld -> (# State# RealWorld, () #))
-> State# RealWorld
-> (# State# RealWorld, Weak# () #)
mkWeak# MutVar# RealWorld Finalizers
r# () (IO () -> State# RealWorld -> (# State# RealWorld, () #)
forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
unIO (IO () -> State# RealWorld -> (# State# RealWorld, () #))
-> IO () -> State# RealWorld -> (# State# RealWorld, () #)
forall a b. (a -> b) -> a -> b
$ IORef Finalizers -> IO ()
foreignPtrFinalizer IORef Finalizers
r) State# RealWorld
s of {
                (# State# RealWorld
s1, Weak# ()
_ #) -> (# State# RealWorld
s1, () #) }}
     else () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
addForeignPtrConcFinalizer_ f :: ForeignPtrContents
f@(MallocPtr MutableByteArray# RealWorld
fo IORef Finalizers
r) IO ()
finalizer = do
  Bool
noFinalizers <- IORef Finalizers -> IO () -> IO Bool
insertHaskellFinalizer IORef Finalizers
r IO ()
finalizer
  if Bool
noFinalizers
     then  (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
               case MutableByteArray# RealWorld
-> ()
-> (State# RealWorld -> (# State# RealWorld, () #))
-> State# RealWorld
-> (# State# RealWorld, Weak# () #)
mkWeak# MutableByteArray# RealWorld
fo () State# RealWorld -> (# State# RealWorld, () #)
finalizer' State# RealWorld
s of
                  (# State# RealWorld
s1, Weak# ()
_ #) -> (# State# RealWorld
s1, () #)
     else () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  where
    finalizer' :: State# RealWorld -> (# State# RealWorld, () #)
    finalizer' :: State# RealWorld -> (# State# RealWorld, () #)
finalizer' = IO () -> State# RealWorld -> (# State# RealWorld, () #)
forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
unIO (IORef Finalizers -> IO ()
foreignPtrFinalizer IORef Finalizers
r IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ForeignPtrContents -> IO ()
touch ForeignPtrContents
f)

addForeignPtrConcFinalizer_ ForeignPtrContents
_ IO ()
_ =
  String -> IO ()
forall a. String -> a
errorWithoutStackTrace String
"GHC.ForeignPtr: attempt to add a finalizer to plain pointer or a final pointer"

insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool
insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool
insertHaskellFinalizer IORef Finalizers
r IO ()
f = do
  !Bool
wasEmpty <- IORef Finalizers -> (Finalizers -> (Finalizers, Bool)) -> IO Bool
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORefP IORef Finalizers
r ((Finalizers -> (Finalizers, Bool)) -> IO Bool)
-> (Finalizers -> (Finalizers, Bool)) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Finalizers
finalizers -> case Finalizers
finalizers of
      Finalizers
NoFinalizers -> ([IO ()] -> Finalizers
HaskellFinalizers [IO ()
f], Bool
True)
      HaskellFinalizers [IO ()]
fs -> ([IO ()] -> Finalizers
HaskellFinalizers (IO ()
fIO () -> [IO ()] -> [IO ()]
forall a. a -> [a] -> [a]
:[IO ()]
fs), Bool
False)
      Finalizers
_ -> (Finalizers, Bool)
forall a. a
noMixingError
  Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
wasEmpty

-- | A box around Weak#, private to this module.
data MyWeak = MyWeak (Weak# ())

insertCFinalizer ::
  IORef Finalizers -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
insertCFinalizer :: forall value.
IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
insertCFinalizer IORef Finalizers
r Addr#
fp Int#
flag Addr#
ep Addr#
p value
val = do
  MyWeak Weak# ()
w <- IORef Finalizers -> value -> IO MyWeak
forall value. IORef Finalizers -> value -> IO MyWeak
ensureCFinalizerWeak IORef Finalizers
r value
val
  (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case Addr#
-> Addr#
-> Int#
-> Addr#
-> Weak# ()
-> State# RealWorld
-> (# State# RealWorld, Int# #)
forall b.
Addr#
-> Addr#
-> Int#
-> Addr#
-> Weak# b
-> State# RealWorld
-> (# State# RealWorld, Int# #)
addCFinalizerToWeak# Addr#
fp Addr#
p Int#
flag Addr#
ep Weak# ()
w State# RealWorld
s of
      (# State# RealWorld
s1, Int#
1# #) -> (# State# RealWorld
s1, () #)

      -- Failed to add the finalizer because some other thread
      -- has finalized w by calling foreignPtrFinalizer. We retry now.
      -- This won't be an infinite loop because that thread must have
      -- replaced the content of r before calling finalizeWeak#.
      (# State# RealWorld
s1, Int#
_ #) -> IO () -> State# RealWorld -> (# State# RealWorld, () #)
forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
unIO (IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
forall value.
IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
insertCFinalizer IORef Finalizers
r Addr#
fp Int#
flag Addr#
ep Addr#
p value
val) State# RealWorld
s1

-- Read the weak reference from an IORef Finalizers, creating it if necessary.
-- Throws an exception if HaskellFinalizers is encountered.
ensureCFinalizerWeak :: IORef Finalizers -> value -> IO MyWeak
ensureCFinalizerWeak :: forall value. IORef Finalizers -> value -> IO MyWeak
ensureCFinalizerWeak ref :: IORef Finalizers
ref@(IORef (STRef MutVar# RealWorld Finalizers
r#)) value
value = do
  Finalizers
fin <- IORef Finalizers -> IO Finalizers
forall a. IORef a -> IO a
readIORef IORef Finalizers
ref
  case Finalizers
fin of
      CFinalizers Weak# ()
weak -> MyWeak -> IO MyWeak
forall (m :: * -> *) a. Monad m => a -> m a
return (Weak# () -> MyWeak
MyWeak Weak# ()
weak)
      HaskellFinalizers{} -> IO MyWeak
forall a. a
noMixingError
      Finalizers
NoFinalizers -> (State# RealWorld -> (# State# RealWorld, MyWeak #)) -> IO MyWeak
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, MyWeak #)) -> IO MyWeak)
-> (State# RealWorld -> (# State# RealWorld, MyWeak #))
-> IO MyWeak
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
          case MutVar# RealWorld Finalizers
-> () -> State# RealWorld -> (# State# RealWorld, Weak# () #)
mkWeakNoFinalizer# MutVar# RealWorld Finalizers
r# (value -> ()
forall a b. a -> b
unsafeCoerce value
value) State# RealWorld
s of { (# State# RealWorld
s1, Weak# ()
w #) ->
             -- See Note [MallocPtr finalizers] (#10904)
          case MutVar# RealWorld Finalizers
-> (Finalizers -> (Finalizers, (MyWeak, Bool)))
-> State# RealWorld
-> (# State# RealWorld, Finalizers, (Finalizers, (MyWeak, Bool)) #)
forall d a c.
MutVar# d a -> (a -> c) -> State# d -> (# State# d, a, c #)
atomicModifyMutVar2# MutVar# RealWorld Finalizers
r# (Weak# () -> Finalizers -> (Finalizers, (MyWeak, Bool))
update Weak# ()
w) State# RealWorld
s1 of
              { (# State# RealWorld
s2, Finalizers
_, (Finalizers
_, (MyWeak
weak, Bool
needKill )) #) ->
          if Bool
needKill
            then case Weak# ()
-> State# RealWorld
-> (# State# RealWorld, Int#,
      State# RealWorld -> (# State# RealWorld, Any #) #)
forall a b.
Weak# a
-> State# RealWorld
-> (# State# RealWorld, Int#,
      State# RealWorld -> (# State# RealWorld, b #) #)
finalizeWeak# Weak# ()
w State# RealWorld
s2 of { (# State# RealWorld
s3, Int#
_, State# RealWorld -> (# State# RealWorld, Any #)
_ #) ->
              (# State# RealWorld
s3, MyWeak
weak #) }
            else (# State# RealWorld
s2, MyWeak
weak #) }}
  where
      update :: Weak# () -> Finalizers -> (Finalizers, (MyWeak, Bool))
update Weak# ()
_ fin :: Finalizers
fin@(CFinalizers Weak# ()
w) = (Finalizers
fin, (Weak# () -> MyWeak
MyWeak Weak# ()
w, Bool
True))
      update Weak# ()
w Finalizers
NoFinalizers = (Weak# () -> Finalizers
CFinalizers Weak# ()
w, (Weak# () -> MyWeak
MyWeak Weak# ()
w, Bool
False))
      update Weak# ()
_ Finalizers
_ = (Finalizers, (MyWeak, Bool))
forall a. a
noMixingError

noMixingError :: a
noMixingError :: forall a. a
noMixingError = String -> a
forall a. String -> a
errorWithoutStackTrace (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$
   String
"GHC.ForeignPtr: attempt to mix Haskell and C finalizers " String -> ShowS
forall a. [a] -> [a] -> [a]
++
   String
"in the same ForeignPtr"

-- Swap out the finalizers with NoFinalizers and then run them.
foreignPtrFinalizer :: IORef Finalizers -> IO ()
foreignPtrFinalizer :: IORef Finalizers -> IO ()
foreignPtrFinalizer IORef Finalizers
r = do
  Finalizers
fs <- IORef Finalizers -> Finalizers -> IO Finalizers
forall a. IORef a -> a -> IO a
atomicSwapIORef IORef Finalizers
r Finalizers
NoFinalizers
             -- atomic, see #7170
  case Finalizers
fs of
    Finalizers
NoFinalizers -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    CFinalizers Weak# ()
w -> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case Weak# ()
-> State# RealWorld
-> (# State# RealWorld, Int#,
      State# RealWorld -> (# State# RealWorld, () #) #)
forall a b.
Weak# a
-> State# RealWorld
-> (# State# RealWorld, Int#,
      State# RealWorld -> (# State# RealWorld, b #) #)
finalizeWeak# Weak# ()
w State# RealWorld
s of
        (# State# RealWorld
s1, Int#
1#, State# RealWorld -> (# State# RealWorld, () #)
f #) -> State# RealWorld -> (# State# RealWorld, () #)
f State# RealWorld
s1
        (# State# RealWorld
s1, Int#
_, State# RealWorld -> (# State# RealWorld, () #)
_ #) -> (# State# RealWorld
s1, () #)
    HaskellFinalizers [IO ()]
actions -> [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [IO ()]
actions

newForeignPtr_ :: Ptr a -> IO (ForeignPtr a)
-- ^Turns a plain memory reference into a foreign pointer that may be
-- associated with finalizers by using 'addForeignPtrFinalizer'.
newForeignPtr_ :: forall a. Ptr a -> IO (ForeignPtr a)
newForeignPtr_ (Ptr Addr#
obj) =  do
  IORef Finalizers
r <- Finalizers -> IO (IORef Finalizers)
forall a. a -> IO (IORef a)
newIORef Finalizers
NoFinalizers
  ForeignPtr a -> IO (ForeignPtr a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
obj (IORef Finalizers -> ForeignPtrContents
PlainForeignPtr IORef Finalizers
r))

withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
-- ^This is a way to look at the pointer living inside a
-- foreign object.  This function takes a function which is
-- applied to that pointer. The resulting 'IO' action is then
-- executed. The foreign object is kept alive at least during
-- the whole action, even if it is not used directly
-- inside. Note that it is not safe to return the pointer from
-- the action and use it after the action completes. All uses
-- of the pointer should be inside the
-- 'withForeignPtr' bracket.  The reason for
-- this unsafeness is the same as for
-- 'unsafeForeignPtrToPtr' below: the finalizer
-- may run earlier than expected, because the compiler can only
-- track usage of the 'ForeignPtr' object, not
-- a 'Ptr' object made from it.
--
-- This function is normally used for marshalling data to
-- or from the object pointed to by the
-- 'ForeignPtr', using the operations from the
-- 'Storable' class.
withForeignPtr :: forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr fo :: ForeignPtr a
fo@(ForeignPtr Addr#
_ ForeignPtrContents
r) Ptr a -> IO b
f = (State# RealWorld -> (# State# RealWorld, b #)) -> IO b
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, b #)) -> IO b)
-> (State# RealWorld -> (# State# RealWorld, b #)) -> IO b
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
  case Ptr a -> IO b
f (ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
fo) of
    IO State# RealWorld -> (# State# RealWorld, b #)
action# -> ForeignPtrContents
-> State# RealWorld
-> (State# RealWorld -> (# State# RealWorld, b #))
-> (# State# RealWorld, b #)
keepAlive# ForeignPtrContents
r State# RealWorld
s State# RealWorld -> (# State# RealWorld, b #)
action#

-- | This is similar to 'withForeignPtr' but comes with an important caveat:
-- the user must guarantee that the continuation does not diverge (e.g. loop or
-- throw an exception). In exchange for this loss of generality, this function
-- offers the ability of GHC to optimise more aggressively.
--
-- 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 :: forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr a
fo Ptr a -> IO b
f = do
  b
r <- Ptr a -> IO b
f (ForeignPtr a -> Ptr a
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr a
fo)
  ForeignPtr a -> IO ()
forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr a
fo
  b -> IO b
forall (m :: * -> *) a. Monad m => a -> m a
return b
r

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. 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
-- ordering robustly requires explicit synchronisation using @MVar@s
-- between the finalizers, but even then the runtime sometimes runs
-- multiple finalizers sequentially in a single thread (for
-- performance reasons), so synchronisation between finalizers could
-- result in artificial deadlock.  Another alternative is to use
-- explicit reference counting.
--
touchForeignPtr :: forall a. ForeignPtr a -> IO ()
touchForeignPtr (ForeignPtr Addr#
_ ForeignPtrContents
r) = ForeignPtrContents -> IO ()
touch ForeignPtrContents
r

touch :: ForeignPtrContents -> IO ()
touch :: ForeignPtrContents -> IO ()
touch ForeignPtrContents
r = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case ForeignPtrContents -> State# RealWorld -> State# RealWorld
touch# ForeignPtrContents
r State# RealWorld
s of State# RealWorld
s' -> (# State# RealWorld
s', () #)

unsafeForeignPtrToPtr :: ForeignPtr a -> Ptr a
-- ^This function extracts the pointer component of a foreign
-- pointer.  This is a potentially dangerous operations, as if the
-- argument to 'unsafeForeignPtrToPtr' is the last usage
-- occurrence of the given foreign pointer, then its finalizer(s) will
-- be run, which potentially invalidates the plain pointer just
-- obtained.  Hence, 'touchForeignPtr' must be used
-- wherever it has to be guaranteed that the pointer lives on - i.e.,
-- has another usage occurrence.
--
-- To avoid subtle coding errors, hand written marshalling code
-- should preferably use 'Foreign.ForeignPtr.withForeignPtr' rather
-- than combinations of 'unsafeForeignPtrToPtr' and
-- 'touchForeignPtr'.  However, the latter routines
-- are occasionally preferred in tool generated marshalling code.
unsafeForeignPtrToPtr :: forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr (ForeignPtr Addr#
fo ForeignPtrContents
_) = Addr# -> Ptr a
forall a. Addr# -> Ptr a
Ptr Addr#
fo

castForeignPtr :: ForeignPtr a -> ForeignPtr b
-- ^This function casts a 'ForeignPtr'
-- parameterised by one type into another type.
castForeignPtr :: forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr = ForeignPtr a -> ForeignPtr b
coerce

plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b
-- ^Advances the given address by the given offset in bytes.
--
-- The new 'ForeignPtr' shares the finalizer of the original,
-- equivalent from a finalization standpoint to just creating another
-- reference to the original. That is, the finalizer will not be
-- called before the new 'ForeignPtr' is unreachable, nor will it be
-- called an additional time due to this call, and the finalizer will
-- be called with the same address that it would have had this call
-- not happened, *not* the new address.
--
-- @since 4.10.0.0
plusForeignPtr :: forall a b. ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr (ForeignPtr Addr#
addr ForeignPtrContents
c) (I# Int#
d) = Addr# -> ForeignPtrContents -> ForeignPtr b
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (Addr# -> Int# -> Addr#
plusAddr# Addr#
addr Int#
d) ForeignPtrContents
c

-- | Causes the finalizers associated with a foreign pointer to be run
-- immediately. The foreign pointer must not be used again after this
-- function is called. If the foreign pointer does not support finalizers,
-- this is a no-op.
finalizeForeignPtr :: ForeignPtr a -> IO ()
finalizeForeignPtr :: forall a. ForeignPtr a -> IO ()
finalizeForeignPtr (ForeignPtr Addr#
_ ForeignPtrContents
c) = case ForeignPtrContents
c of
  PlainForeignPtr IORef Finalizers
ref -> IORef Finalizers -> IO ()
foreignPtrFinalizer IORef Finalizers
ref
  MallocPtr MutableByteArray# RealWorld
_ IORef Finalizers
ref -> IORef Finalizers -> IO ()
foreignPtrFinalizer IORef Finalizers
ref
  PlainPtr{} -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  FinalPtr{} -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

{- $commentary

This is a high-level overview of how 'ForeignPtr' works.
The implementation of 'ForeignPtr' must accomplish several goals:

1. Invoke a finalizer once a foreign pointer becomes unreachable.
2. Support augmentation of finalizers, i.e. 'addForeignPtrFinalizer'.
   As a motivating example, suppose that the payload of a foreign
   pointer is C struct @bar@ that has an optionally NULL pointer field
   @foo@ to an unmanaged heap object. Initially, @foo@ is NULL, and
   later the program uses @malloc@, initializes the object, and assigns
   @foo@ the address returned by @malloc@. When the foreign pointer
   becomes unreachable, it is now necessary to first @free@ the object
   pointed to by @foo@ and then invoke whatever finalizer was associated
   with @bar@. That is, finalizers must be invoked in the opposite order
   they are added.
3. Allow users to invoke a finalizer promptly if they know that the
   foreign pointer is unreachable, i.e. 'finalizeForeignPtr'.

How can these goals be accomplished? Goal 1 suggests that weak references
and finalizers (via 'Weak#' and 'mkWeak#') are necessary. But how should
they be used and what should their key be?  Certainly not 'ForeignPtr' or
'ForeignPtrContents'. See the warning in "GHC.Weak" about weak pointers with
lifted (non-primitive) keys. The two finalizer-supporting data constructors of
'ForeignPtr' have an @'IORef' 'Finalizers'@ (backed by 'MutVar#') field.
This gets used in two different ways depending on the kind of finalizer:

* 'HaskellFinalizers': The first @addForeignPtrConcFinalizer_@ call uses
  'mkWeak#' to attach the finalizer @foreignPtrFinalizer@ to the 'MutVar#'.
  The resulting 'Weak#' is discarded (see @addForeignPtrConcFinalizer_@).
  Subsequent calls to @addForeignPtrConcFinalizer_@ (goal 2) just add
  finalizers onto the list in the 'HaskellFinalizers' data constructor.
* 'CFinalizers': The first 'addForeignPtrFinalizer' call uses
  'mkWeakNoFinalizer#' to create a 'Weak#'. The 'Weak#' is preserved in the
  'CFinalizers' data constructor. Both the first call and subsequent
  calls (goal 2) use 'addCFinalizerToWeak#' to attach finalizers to the
  'Weak#' itself. Also, see Note [MallocPtr finalizers] for discussion of
  the key and value of this 'Weak#'.

In either case, the runtime invokes the appropriate finalizers when the
'ForeignPtr' becomes unreachable.
-}