X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Foreign%2FForeignPtr.hs;h=21485dba2ea036600b27d82e3b60879dcceab5cf;hb=147524c1f05f6e1bf721c1b35fd0d8672f25a883;hp=a0bccf59b8564c2c97ca2a74ad82ee14948934d6;hpb=7d090bf5e03ee22db47edfd73a0b542b32408704;p=ghc-base.git diff --git a/Foreign/ForeignPtr.hs b/Foreign/ForeignPtr.hs index a0bccf5..21485db 100644 --- a/Foreign/ForeignPtr.hs +++ b/Foreign/ForeignPtr.hs @@ -1,4 +1,4 @@ -{-# OPTIONS -fno-implicit-prelude #-} +{-# OPTIONS_GHC -fno-implicit-prelude #-} ----------------------------------------------------------------------------- -- | -- Module : Foreign.ForeignPtr @@ -20,14 +20,14 @@ module Foreign.ForeignPtr -- * Finalised data pointers ForeignPtr , FinalizerPtr -#ifdef __HUGS__ +#if defined(__HUGS__) || defined(__GLASGOW_HASKELL__) , FinalizerEnvPtr #endif -- ** Basic operations , newForeignPtr , newForeignPtr_ , addForeignPtrFinalizer -#ifdef __HUGS__ +#if defined(__HUGS__) || defined(__GLASGOW_HASKELL__) , newForeignPtrEnv , addForeignPtrFinalizerEnv #endif @@ -86,10 +86,6 @@ import GHC.ForeignPtr #if !defined(__NHC__) && !defined(__GLASGOW_HASKELL__) import Foreign.Marshal.Alloc ( malloc, mallocBytes, finalizerFree ) -import Data.Typeable - -#include "Typeable.h" -INSTANCE_TYPEABLE1(ForeignPtr,foreignPtrTc,"ForeignPtr") instance Eq (ForeignPtr a) where p == q = unsafeForeignPtrToPtr p == unsafeForeignPtrToPtr q @@ -109,8 +105,9 @@ newForeignPtr :: FinalizerPtr a -> Ptr a -> IO (ForeignPtr a) -- 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. +-- manager. Indeed, there is no guarantee that the finalizer is executed at +-- all; a program may exit with finalizers outstanding. (This is true +-- of GHC, other implementations may give stronger guarantees). newForeignPtr finalizer p = do fObj <- newForeignPtr_ p addForeignPtrFinalizer finalizer fObj @@ -142,7 +139,7 @@ withForeignPtr fo io return r #endif /* ! __NHC__ */ -#ifdef __HUGS__ +#if defined(__HUGS__) || defined(__GLASGOW_HASKELL__) -- | This variant of 'newForeignPtr' adds a finalizer that expects an -- environment in addition to the finalized pointer. The environment -- that will be passed to the finalizer is fixed by the second argument to @@ -155,6 +152,24 @@ newForeignPtrEnv finalizer env p return fObj #endif /* __HUGS__ */ +#ifdef __GLASGOW_HASKELL__ +type FinalizerEnvPtr env a = FunPtr (Ptr env -> Ptr 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 finalizer env fptr = + addForeignPtrConcFinalizer fptr + (mkFinalizerEnv finalizer env (unsafeForeignPtrToPtr fptr)) + +foreign import ccall "dynamic" + mkFinalizerEnv :: FinalizerEnvPtr env a -> Ptr env -> Ptr a -> IO () +#endif + + #ifndef __GLASGOW_HASKELL__ mallocForeignPtr :: Storable a => IO (ForeignPtr a) mallocForeignPtr = do @@ -174,7 +189,7 @@ mallocForeignPtrBytes n = do mallocForeignPtrArray :: Storable a => Int -> IO (ForeignPtr a) mallocForeignPtrArray = doMalloc undefined where - doMalloc :: Storable a => a -> Int -> IO (ForeignPtr a) + doMalloc :: Storable b => b -> Int -> IO (ForeignPtr b) doMalloc dummy size = mallocForeignPtrBytes (size * sizeOf dummy) -- | This function is similar to 'Foreign.Marshal.Array.mallocArray0',