X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=Foreign%2FForeignPtr.hs;h=160bf3c99948c3424a629abbb2f0d768db7bc622;hb=30464c0cb915c2ae900909568fa8677bba341e45;hp=9705181ab0e27931377208bd25290f50493d48fa;hpb=bbbe42147fd9666c2c00d7097ac381a3ff437958;p=haskell-directory.git diff --git a/Foreign/ForeignPtr.hs b/Foreign/ForeignPtr.hs index 9705181..160bf3c 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,29 @@ module Foreign.ForeignPtr -- * Finalised data pointers ForeignPtr , FinalizerPtr +#if defined(__HUGS__) || defined(__GLASGOW_HASKELL__) + , FinalizerEnvPtr +#endif + -- ** Basic operations , newForeignPtr , newForeignPtr_ , addForeignPtrFinalizer +#if defined(__HUGS__) || defined(__GLASGOW_HASKELL__) + , newForeignPtrEnv + , addForeignPtrFinalizerEnv +#endif , withForeignPtr + +#ifdef __GLASGOW_HASKELL__ + , finalizeForeignPtr +#endif + + -- ** Low-level operations , unsafeForeignPtrToPtr , touchForeignPtr , castForeignPtr + -- ** Allocating managed memory , mallocForeignPtr , mallocForeignPtrBytes , mallocForeignPtrArray @@ -71,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 @@ -111,7 +122,7 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- the action and use it after the action completes. All uses -- of the pointer should be inside the -- 'withForeignPtr' bracket. The reason for --- this unsafety is the same as 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 @@ -127,6 +138,37 @@ withForeignPtr fo io return r #endif /* ! __NHC__ */ +#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 +-- 'newForeignPtrEnv'. +newForeignPtrEnv :: + FinalizerEnvPtr env a -> Ptr env -> Ptr a -> IO (ForeignPtr a) +newForeignPtrEnv finalizer env p + = do fObj <- newForeignPtr_ p + addForeignPtrFinalizerEnv finalizer env fObj + 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 @@ -137,13 +179,21 @@ mallocForeignPtrBytes :: Int -> IO (ForeignPtr a) mallocForeignPtrBytes n = do r <- mallocBytes n newForeignPtr finalizerFree r -#endif /* __HUGS__ || __NHC__ */ +#endif /* !__GLASGOW_HASKELL__ */ +-- | This function is similar to 'Foreign.Marshal.Array.mallocArray', +-- but yields a memory area that has a finalizer attached that releases +-- the memory area. As with 'mallocForeignPtr', it is not guaranteed that +-- the block of memory was allocated by 'Foreign.Marshal.Alloc.malloc'. 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', +-- but yields a memory area that has a finalizer attached that releases +-- the memory area. As with 'mallocForeignPtr', it is not guaranteed that +-- the block of memory was allocated by 'Foreign.Marshal.Alloc.malloc'. mallocForeignPtrArray0 :: Storable a => Int -> IO (ForeignPtr a) mallocForeignPtrArray0 size = mallocForeignPtrArray (size + 1)