(
ForeignPtr(..),
FinalizerPtr,
- newForeignPtr,
+ newForeignPtr_,
mallocForeignPtr,
mallocForeignPtrBytes,
addForeignPtrFinalizer,
touchForeignPtr,
- foreignPtrToPtr,
+ unsafeForeignPtrToPtr,
castForeignPtr,
newConcForeignPtr,
addForeignPtrConcFinalizer,
import Control.Monad ( sequence_ )
import Foreign.Ptr
import Foreign.Storable
-import Data.Dynamic
+import Data.Typeable
import GHC.List ( null )
import GHC.Base
| MallocPtr (MutableByteArray# RealWorld) !(IORef [IO ()])
instance Eq (ForeignPtr a) where
- p == q = foreignPtrToPtr p == foreignPtrToPtr q
+ p == q = unsafeForeignPtrToPtr p == unsafeForeignPtrToPtr q
instance Ord (ForeignPtr a) where
- compare p q = compare (foreignPtrToPtr p) (foreignPtrToPtr q)
+ compare p q = compare (unsafeForeignPtrToPtr p) (unsafeForeignPtrToPtr q)
instance Show (ForeignPtr a) where
- showsPrec p f = showsPrec p (foreignPtrToPtr f)
+ showsPrec p f = showsPrec p (unsafeForeignPtrToPtr f)
-#include "Dynamic.h"
+#include "Typeable.h"
INSTANCE_TYPEABLE1(ForeignPtr,foreignPtrTc,"ForeignPtr")
-- |A Finaliser is represented as a pointer to a foreign function that, at
--
type FinalizerPtr a = FunPtr (Ptr a -> IO ())
-newForeignPtr :: Ptr a -> FinalizerPtr a -> IO (ForeignPtr a)
--- ^Turns a plain memory reference into a foreign object by
--- associating a finaliser with the reference. The finaliser will be executed
--- after the last reference to the foreign object is dropped. Note that there
--- is no guarantee on how soon the finaliser is executed after the last
--- reference was dropped; this depends on the details of the Haskell storage
--- manager. The only guarantee is that the finaliser runs before the program
--- terminates.
-newForeignPtr p finalizer
- = do fObj <- mkForeignPtr p
- addForeignPtrFinalizer fObj finalizer
- return fObj
-
newConcForeignPtr :: Ptr a -> IO () -> IO (ForeignPtr a)
-- ^Turns a plain memory reference into a foreign object
-- by associating a finaliser - given by the monadic operation
-- The finalizer, when invoked, will run in a separate thread.
--
newConcForeignPtr p finalizer
- = do fObj <- mkForeignPtr p
+ = do fObj <- newForeignPtr_ p
addForeignPtrConcFinalizer fObj finalizer
return fObj
(# s, MallocPtr mbarr# r #)
}
-addForeignPtrFinalizer :: ForeignPtr a -> FinalizerPtr a -> IO ()
+addForeignPtrFinalizer :: FinalizerPtr a -> ForeignPtr a -> IO ()
-- ^This function adds a finaliser to the given foreign object. The
-- finalizer will run /before/ all other finalizers for the same
-- object which have already been registered.
-addForeignPtrFinalizer fptr finalizer =
+addForeignPtrFinalizer finalizer fptr =
addForeignPtrConcFinalizer fptr
- (mkFinalizer finalizer (foreignPtrToPtr fptr))
+ (mkFinalizer finalizer (unsafeForeignPtrToPtr fptr))
addForeignPtrConcFinalizer :: ForeignPtr a -> IO () -> IO ()
-- ^This function adds a finaliser to the given @ForeignPtr@. The
writeIORef r (finalizer : fs)
if (null fs)
then IO $ \s ->
- let p = foreignPtrToPtr f in
+ let p = unsafeForeignPtrToPtr f in
case mkWeak# fo () (foreignPtrFinalizer r p) s of
(# s1, w #) -> (# s1, () #)
else return ()
writeIORef r (finalizer : fs)
if (null fs)
then IO $ \s ->
- let p = foreignPtrToPtr f in
+ let p = unsafeForeignPtrToPtr f in
case mkWeak# fo () (foreignPtrFinalizer r p) s of
(# s1, w #) -> (# s1, () #)
else return ()
fs <- readIORef r
sequence_ fs
-mkForeignPtr :: Ptr a -> IO (ForeignPtr a) {- not exported -}
-mkForeignPtr (Ptr obj) = do
+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 obj) = do
r <- newIORef []
IO $ \ s# ->
case mkForeignObj# obj s# of
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 'withForeignPtr'
+-- actions. In particular 'Foreign.ForeignPtr.withForeignPtr'
-- does a 'touchForeignPtr' after it
-- executes the user action.
--
touchForeignPtr (MallocPtr fo r)
= IO $ \s -> case touch# fo s of s -> (# s, () #)
-foreignPtrToPtr :: ForeignPtr a -> Ptr a
+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 'foreignPtrToPtr' is the last usage
+-- argument to 'unsafeForeignPtrToPtr' is the last usage
-- occurence of the given foreign pointer, then its finaliser(s) will
-- be run, which potentially invalidates the plain pointer just
-- obtained. Hence, 'touchForeignPtr' must be used
-- has another usage occurrence.
--
-- To avoid subtle coding errors, hand written marshalling code
--- should preferably use 'withForeignPtr' rather
--- than combinations of 'foreignPtrToPtr' and
+-- should preferably use 'Foreign.ForeignPtr.withForeignPtr' rather
+-- than combinations of 'unsafeForeignPtrToPtr' and
-- 'touchForeignPtr'. However, the later routines
-- are occasionally preferred in tool generated marshalling code.
-foreignPtrToPtr (ForeignPtr fo r) = Ptr (foreignObjToAddr# fo)
-foreignPtrToPtr (MallocPtr fo r) = Ptr (byteArrayContents# (unsafeCoerce# fo))
+unsafeForeignPtrToPtr (ForeignPtr fo r) = Ptr (foreignObjToAddr# fo)
+unsafeForeignPtrToPtr (MallocPtr fo r) = Ptr (byteArrayContents# (unsafeCoerce# fo))
castForeignPtr :: ForeignPtr a -> ForeignPtr b
-- ^This function casts a 'ForeignPtr'