{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE Unsafe #-}
{-# OPTIONS_HADDOCK not-home #-}
module GHC.ForeignPtr
  (
        
        ForeignPtr(..),
        ForeignPtrContents(..),
        Finalizers(..),
        FinalizerPtr,
        FinalizerEnvPtr,
        
        newForeignPtr_,
        mallocForeignPtr,
        mallocPlainForeignPtr,
        mallocForeignPtrBytes,
        mallocPlainForeignPtrBytes,
        mallocForeignPtrAlignedBytes,
        mallocPlainForeignPtrAlignedBytes,
        newConcForeignPtr,
        
        addForeignPtrFinalizer,
        addForeignPtrFinalizerEnv,
        addForeignPtrConcFinalizer,
        
        unsafeForeignPtrToPtr,
        castForeignPtr,
        plusForeignPtr,
        
        withForeignPtr,
        unsafeWithForeignPtr,
        touchForeignPtr,
        
        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(..) )
import Unsafe.Coerce    ( unsafeCoerce )
data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents
        
        
        
        
        
        
        
        
        
        
        
data Finalizers
  = NoFinalizers
    
    
    
  | CFinalizers (Weak# ())
    
  | HaskellFinalizers [IO ()]
    
data ForeignPtrContents
  = PlainForeignPtr !(IORef Finalizers)
    
    
    
  | FinalPtr
    
    
    
    
    
    
    
  | MallocPtr (MutableByteArray# RealWorld) !(IORef Finalizers)
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  | PlainPtr (MutableByteArray# RealWorld)
    
    
    
    
    
    
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
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)
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)
type FinalizerPtr a        = FunPtr (Ptr a -> IO ())
type FinalizerEnvPtr env a = FunPtr (Ptr env -> Ptr a -> IO ())
newConcForeignPtr :: Ptr a -> IO () -> IO (ForeignPtr a)
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 a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ForeignPtr a
fObj
mallocForeignPtr :: Storable a => IO (ForeignPtr a)
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
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) #)
     }
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) #)
     }
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
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#) #)
     }
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 ()
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"
addForeignPtrFinalizerEnv ::
  FinalizerEnvPtr env a -> Ptr env -> ForeignPtr a -> IO ()
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 ()
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# () #)
forall a b c.
a
-> b
-> (State# RealWorld -> (# State# RealWorld, c #))
-> State# RealWorld
-> (# State# RealWorld, Weak# b #)
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 a. a -> IO a
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# () #)
forall a b c.
a
-> b
-> (State# RealWorld -> (# State# RealWorld, c #))
-> State# RealWorld
-> (# State# RealWorld, Weak# b #)
mkWeak# MutableByteArray# RealWorld
fo () State# RealWorld -> (# State# RealWorld, () #)
finalizer' State# RealWorld
s of
                  (# State# RealWorld
s1, Weak# ()
_ #) -> (# State# RealWorld
s1, () #)
     else () -> IO ()
forall a. a -> IO a
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 a b. IO a -> IO b -> IO b
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 a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
wasEmpty
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, () #)
      
      
      
      
      (# 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
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 a. a -> IO a
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# () #)
forall a b.
a -> b -> State# RealWorld -> (# State# RealWorld, Weak# b #)
mkWeakNoFinalizer# MutVar# RealWorld Finalizers
r# (value -> ()
forall a b. a -> b
unsafeCoerce value
value) State# RealWorld
s of { (# State# RealWorld
s1, Weak# ()
w #) ->
             
          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"
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
             
  case Finalizers
fs of
    Finalizers
NoFinalizers -> () -> IO ()
forall a. a -> IO a
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)
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 a. a -> IO 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
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 #)
forall a b. a -> State# RealWorld -> (State# RealWorld -> b) -> b
keepAlive# ForeignPtrContents
r State# RealWorld
s State# RealWorld -> (# State# RealWorld, b #)
action#
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 a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
touchForeignPtr :: ForeignPtr a -> IO ()
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
forall a. a -> State# RealWorld -> State# RealWorld
touch# ForeignPtrContents
r State# RealWorld
s of State# RealWorld
s' -> (# State# RealWorld
s', () #)
unsafeForeignPtrToPtr :: ForeignPtr a -> Ptr a
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
castForeignPtr :: forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr = ForeignPtr a -> ForeignPtr b
forall a b. Coercible a b => a -> b
coerce
plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b
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
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 a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  FinalPtr{} -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()