{-# LANGUAGE Unsafe #-}
{-# LANGUAGE NoImplicitPrelude
           , BangPatterns
           , MagicHash
           , UnboxedTuples
  #-}
{-# OPTIONS_HADDOCK not-home #-}
{-# LANGUAGE StandaloneDeriving #-}

-----------------------------------------------------------------------------
-- |
-- 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
  (
        ForeignPtr(..),
        ForeignPtrContents(..),
        FinalizerPtr,
        FinalizerEnvPtr,
        newForeignPtr_,
        mallocForeignPtr,
        mallocPlainForeignPtr,
        mallocForeignPtrBytes,
        mallocPlainForeignPtrBytes,
        mallocForeignPtrAlignedBytes,
        mallocPlainForeignPtrAlignedBytes,
        addForeignPtrFinalizer,
        addForeignPtrFinalizerEnv,
        touchForeignPtr,
        unsafeForeignPtrToPtr,
        castForeignPtr,
        plusForeignPtr,
        newConcForeignPtr,
        addForeignPtrConcFinalizer,
        finalizeForeignPtr
  ) 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(..) )

-- |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.

data Finalizers
  = NoFinalizers
  | CFinalizers (Weak# ())
  | HaskellFinalizers [IO ()]

data ForeignPtrContents
  = PlainForeignPtr !(IORef Finalizers)
  | MallocPtr      (MutableByteArray# RealWorld) !(IORef Finalizers)
  | PlainPtr       (MutableByteArray# RealWorld)

-- | @since 2.01
instance Eq (ForeignPtr a) where
    p :: ForeignPtr a
p == :: ForeignPtr a -> ForeignPtr a -> Bool
== q :: 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 p :: ForeignPtr a
p q :: 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 p :: Int
p f :: 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 :: Ptr a -> IO () -> IO (ForeignPtr a)
newConcForeignPtr p :: Ptr a
p finalizer :: 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 :: 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 :: b -> IO (ForeignPtr b)
doMalloc a :: b
a
          | Int# -> Int
I# Int#
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = String -> IO (ForeignPtr b)
forall a. String -> a
errorWithoutStackTrace "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
$ \s :: 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 { (# s' :: State# RealWorld
s', mbarr# :: MutableByteArray# RealWorld
mbarr# #) ->
             (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr b
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (ByteArray# -> Addr#
byteArrayContents# (MutableByteArray# RealWorld -> ByteArray#
unsafeCoerce# MutableByteArray# RealWorld
mbarr#))
                               (MutableByteArray# RealWorld
-> IORef Finalizers -> ForeignPtrContents
MallocPtr MutableByteArray# RealWorld
mbarr# IORef Finalizers
r) #)
            }
            where !(I# size :: Int#
size)  = b -> Int
forall a. Storable a => a -> Int
sizeOf b
a
                  !(I# align :: 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 :: Int -> IO (ForeignPtr a)
mallocForeignPtrBytes size :: Int
size | Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 =
  String -> IO (ForeignPtr a)
forall a. String -> a
errorWithoutStackTrace "mallocForeignPtrBytes: size must be >= 0"
mallocForeignPtrBytes (I# size :: 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
$ \s :: 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 { (# s' :: State# RealWorld
s', mbarr# :: MutableByteArray# RealWorld
mbarr# #) ->
       (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (ByteArray# -> Addr#
byteArrayContents# (MutableByteArray# RealWorld -> ByteArray#
unsafeCoerce# 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 :: Int -> Int -> IO (ForeignPtr a)
mallocForeignPtrAlignedBytes size :: Int
size _align :: Int
_align | Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 =
  String -> IO (ForeignPtr a)
forall a. String -> a
errorWithoutStackTrace "mallocForeignPtrAlignedBytes: size must be >= 0"
mallocForeignPtrAlignedBytes (I# size :: Int#
size) (I# align :: 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
$ \s :: 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 { (# s' :: State# RealWorld
s', mbarr# :: MutableByteArray# RealWorld
mbarr# #) ->
       (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (ByteArray# -> Addr#
byteArrayContents# (MutableByteArray# RealWorld -> ByteArray#
unsafeCoerce# 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 :: 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 :: b -> IO (ForeignPtr b)
doMalloc a :: b
a
          | Int# -> Int
I# Int#
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = String -> IO (ForeignPtr b)
forall a. String -> a
errorWithoutStackTrace "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
$ \s :: 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 { (# s' :: State# RealWorld
s', mbarr# :: MutableByteArray# RealWorld
mbarr# #) ->
             (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr b
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (ByteArray# -> Addr#
byteArrayContents# (MutableByteArray# RealWorld -> ByteArray#
unsafeCoerce# MutableByteArray# RealWorld
mbarr#))
                               (MutableByteArray# RealWorld -> ForeignPtrContents
PlainPtr MutableByteArray# RealWorld
mbarr#) #)
            }
            where !(I# size :: Int#
size)  = b -> Int
forall a. Storable a => a -> Int
sizeOf b
a
                  !(I# align :: 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 :: Int -> IO (ForeignPtr a)
mallocPlainForeignPtrBytes size :: Int
size | Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 =
  String -> IO (ForeignPtr a)
forall a. String -> a
errorWithoutStackTrace "mallocPlainForeignPtrBytes: size must be >= 0"
mallocPlainForeignPtrBytes (I# size :: 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
$ \s :: 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 { (# s' :: State# RealWorld
s', mbarr# :: MutableByteArray# RealWorld
mbarr# #) ->
       (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (ByteArray# -> Addr#
byteArrayContents# (MutableByteArray# RealWorld -> ByteArray#
unsafeCoerce# 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 :: Int -> Int -> IO (ForeignPtr a)
mallocPlainForeignPtrAlignedBytes size :: Int
size _align :: Int
_align | Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 =
  String -> IO (ForeignPtr a)
forall a. String -> a
errorWithoutStackTrace "mallocPlainForeignPtrAlignedBytes: size must be >= 0"
mallocPlainForeignPtrAlignedBytes (I# size :: Int#
size) (I# align :: 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
$ \s :: 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 { (# s' :: State# RealWorld
s', mbarr# :: MutableByteArray# RealWorld
mbarr# #) ->
       (# State# RealWorld
s', Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr (ByteArray# -> Addr#
byteArrayContents# (MutableByteArray# RealWorld -> ByteArray#
unsafeCoerce# 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 :: FinalizerPtr a -> ForeignPtr a -> IO ()
addForeignPtrFinalizer (FunPtr fp :: Addr#
fp) (ForeignPtr p :: Addr#
p c :: ForeignPtrContents
c) = case ForeignPtrContents
c of
  PlainForeignPtr r :: 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 0# Addr#
nullAddr# Addr#
p ()
  MallocPtr     _ r :: 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 0# Addr#
nullAddr# Addr#
p ForeignPtrContents
c
  _ -> String -> IO ()
forall a. String -> a
errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain 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 'addForeignPtrFinalizerEnv' but allows the finalizer to be
-- passed an additional environment parameter to be passed to the
-- finalizer.  The environment passed to the finalizer is fixed by the
-- second argument to 'addForeignPtrFinalizerEnv'
addForeignPtrFinalizerEnv :: FinalizerEnvPtr env a -> Ptr env -> ForeignPtr a -> IO ()
addForeignPtrFinalizerEnv (FunPtr fp :: Addr#
fp) (Ptr ep :: Addr#
ep) (ForeignPtr p :: Addr#
p c :: ForeignPtrContents
c) = case ForeignPtrContents
c of
  PlainForeignPtr r :: 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 1# Addr#
ep Addr#
p ()
  MallocPtr     _ r :: 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 1# Addr#
ep Addr#
p ForeignPtrContents
c
  _ -> String -> IO ()
forall a. String -> a
errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain 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 :: ForeignPtr a -> IO () -> IO ()
addForeignPtrConcFinalizer (ForeignPtr _ c :: ForeignPtrContents
c) finalizer :: IO ()
finalizer =
  ForeignPtrContents -> IO () -> IO ()
addForeignPtrConcFinalizer_ ForeignPtrContents
c IO ()
finalizer

addForeignPtrConcFinalizer_ :: ForeignPtrContents -> IO () -> IO ()
addForeignPtrConcFinalizer_ :: ForeignPtrContents -> IO () -> IO ()
addForeignPtrConcFinalizer_ (PlainForeignPtr r :: IORef Finalizers
r) finalizer :: 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
$ \s :: State# RealWorld
s ->
              case IORef Finalizers
r of { IORef (STRef r# :: MutVar# RealWorld Finalizers
r#) ->
              case MutVar# RealWorld Finalizers
-> ()
-> (State# RealWorld -> (# State# RealWorld, () #))
-> State# RealWorld
-> (# State# RealWorld, Weak# () #)
forall k1 a b.
k1
-> a
-> (State# RealWorld -> (# State# RealWorld, b #))
-> State# RealWorld
-> (# State# RealWorld, Weak# a #)
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 {
                (# s1 :: State# RealWorld
s1, _ #) -> (# State# RealWorld
s1, () #) }}
     else () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
addForeignPtrConcFinalizer_ f :: ForeignPtrContents
f@(MallocPtr fo :: MutableByteArray# RealWorld
fo r :: IORef Finalizers
r) finalizer :: 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
$ \s :: State# RealWorld
s ->
               case MutableByteArray# RealWorld
-> ()
-> (State# RealWorld -> (# State# RealWorld, () #))
-> State# RealWorld
-> (# State# RealWorld, Weak# () #)
forall k1 a b.
k1
-> a
-> (State# RealWorld -> (# State# RealWorld, b #))
-> State# RealWorld
-> (# State# RealWorld, Weak# a #)
mkWeak# MutableByteArray# RealWorld
fo () State# RealWorld -> (# State# RealWorld, () #)
finalizer' State# RealWorld
s of
                  (# s1 :: State# RealWorld
s1, _ #) -> (# 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_ _ _ =
  String -> IO ()
forall a. String -> a
errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to plain pointer"

insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool
insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool
insertHaskellFinalizer r :: IORef Finalizers
r f :: 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
finalizers -> case Finalizers
finalizers of
      NoFinalizers -> ([IO ()] -> Finalizers
HaskellFinalizers [IO ()
f], Bool
True)
      HaskellFinalizers fs :: [IO ()]
fs -> ([IO ()] -> Finalizers
HaskellFinalizers (IO ()
fIO () -> [IO ()] -> [IO ()]
forall k1. k1 -> [k1] -> [k1]
:[IO ()]
fs), Bool
False)
      _ -> (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 :: IORef Finalizers
-> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
insertCFinalizer r :: IORef Finalizers
r fp :: Addr#
fp flag :: Int#
flag ep :: Addr#
ep p :: Addr#
p val :: value
val = do
  MyWeak w :: 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
$ \s :: State# RealWorld
s -> case Addr#
-> Addr#
-> Int#
-> Addr#
-> Weak# ()
-> State# RealWorld
-> (# State# RealWorld, Int# #)
forall a.
Addr#
-> Addr#
-> Int#
-> Addr#
-> Weak# a
-> State# RealWorld
-> (# State# RealWorld, Int# #)
addCFinalizerToWeak# Addr#
fp Addr#
p Int#
flag Addr#
ep Weak# ()
w State# RealWorld
s of
      (# s1 :: State# RealWorld
s1, 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#.
      (# s1 :: State# RealWorld
s1, _ #) -> 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

ensureCFinalizerWeak :: IORef Finalizers -> value -> IO MyWeak
ensureCFinalizerWeak :: IORef Finalizers -> value -> IO MyWeak
ensureCFinalizerWeak ref :: IORef Finalizers
ref@(IORef (STRef r# :: MutVar# RealWorld Finalizers
r#)) value :: 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# ()
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
      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
$ \s :: State# RealWorld
s ->
          case MutVar# RealWorld Finalizers
-> () -> State# RealWorld -> (# State# RealWorld, Weak# () #)
forall k1 a.
k1 -> a -> State# RealWorld -> (# State# RealWorld, Weak# a #)
mkWeakNoFinalizer# MutVar# RealWorld Finalizers
r# (value -> ()
unsafeCoerce# value
value) State# RealWorld
s of { (# s1 :: State# RealWorld
s1, w :: 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 k1 b.
MutVar# d k1 -> (k1 -> b) -> State# d -> (# State# d, k1, b #)
atomicModifyMutVar2# MutVar# RealWorld Finalizers
r# (Weak# () -> Finalizers -> (Finalizers, (MyWeak, Bool))
update Weak# ()
w) State# RealWorld
s1 of
              { (# s2 :: State# RealWorld
s2, _, (_, (weak :: MyWeak
weak, needKill :: Bool
needKill )) #) ->
          if Bool
needKill
            then case Weak# ()
-> State# RealWorld
-> (# State# RealWorld, Int#,
      State# RealWorld -> (# State# RealWorld, Any #) #)
forall k1 a.
Weak# k1
-> State# RealWorld
-> (# State# RealWorld, Int#,
      State# RealWorld -> (# State# RealWorld, a #) #)
finalizeWeak# Weak# ()
w State# RealWorld
s2 of { (# s3 :: State# RealWorld
s3, _, _ #) ->
              (# State# RealWorld
s3, MyWeak
weak #) }
            else (# State# RealWorld
s2, MyWeak
weak #) }}
  where
      update :: Weak# () -> Finalizers -> (Finalizers, (MyWeak, Bool))
update _ fin :: Finalizers
fin@(CFinalizers w :: Weak# ()
w) = (Finalizers
fin, (Weak# () -> MyWeak
MyWeak Weak# ()
w, Bool
True))
      update w :: Weak# ()
w NoFinalizers = (Weak# () -> Finalizers
CFinalizers Weak# ()
w, (Weak# () -> MyWeak
MyWeak Weak# ()
w, Bool
False))
      update _ _ = (Finalizers, (MyWeak, Bool))
forall a. a
noMixingError

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

foreignPtrFinalizer :: IORef Finalizers -> IO ()
foreignPtrFinalizer :: IORef Finalizers -> IO ()
foreignPtrFinalizer r :: 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
    NoFinalizers -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    CFinalizers w :: 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
$ \s :: State# RealWorld
s -> case Weak# ()
-> State# RealWorld
-> (# State# RealWorld, Int#,
      State# RealWorld -> (# State# RealWorld, () #) #)
forall k1 a.
Weak# k1
-> State# RealWorld
-> (# State# RealWorld, Int#,
      State# RealWorld -> (# State# RealWorld, a #) #)
finalizeWeak# Weak# ()
w State# RealWorld
s of
        (# s1 :: State# RealWorld
s1, 1#, f :: State# RealWorld -> (# State# RealWorld, () #)
f #) -> State# RealWorld -> (# State# RealWorld, () #)
f State# RealWorld
s1
        (# s1 :: State# RealWorld
s1, _, _ #) -> (# State# RealWorld
s1, () #)
    HaskellFinalizers actions :: [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_ :: Ptr a -> IO (ForeignPtr a)
newForeignPtr_ (Ptr obj :: 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))

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.
--
-- 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 :: ForeignPtr a -> IO ()
touchForeignPtr (ForeignPtr _ r :: ForeignPtrContents
r) = ForeignPtrContents -> IO ()
touch ForeignPtrContents
r

touch :: ForeignPtrContents -> IO ()
touch :: ForeignPtrContents -> IO ()
touch r :: 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
$ \s :: State# RealWorld
s -> case ForeignPtrContents -> State# RealWorld -> State# RealWorld
forall k1. k1 -> State# RealWorld -> State# RealWorld
touch# ForeignPtrContents
r State# RealWorld
s of s' :: 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 :: ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr (ForeignPtr fo :: Addr#
fo _) = 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 :: ForeignPtr a -> ForeignPtr b
castForeignPtr = ForeignPtr a -> ForeignPtr b
forall k1 a. Coercible k1 a => k1 -> a
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 :: ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr (ForeignPtr addr :: Addr#
addr c :: ForeignPtrContents
c) (I# d :: 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.
finalizeForeignPtr :: ForeignPtr a -> IO ()
finalizeForeignPtr :: ForeignPtr a -> IO ()
finalizeForeignPtr (ForeignPtr _ (PlainPtr _)) = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return () -- no effect
finalizeForeignPtr (ForeignPtr _ foreignPtr :: ForeignPtrContents
foreignPtr) = IORef Finalizers -> IO ()
foreignPtrFinalizer IORef Finalizers
refFinalizers
        where
                refFinalizers :: IORef Finalizers
refFinalizers = case ForeignPtrContents
foreignPtr of
                        (PlainForeignPtr ref :: IORef Finalizers
ref) -> IORef Finalizers
ref
                        (MallocPtr     _ ref :: IORef Finalizers
ref) -> IORef Finalizers
ref
                        PlainPtr _            ->
                            String -> IORef Finalizers
forall a. String -> a
errorWithoutStackTrace "finalizeForeignPtr PlainPtr"