ForeignPtr.hs 19.9 KB
Newer Older
1
{-# LANGUAGE Unsafe #-}
2
{-# LANGUAGE NoImplicitPrelude
3 4 5 6
           , BangPatterns
           , MagicHash
           , UnboxedTuples
  #-}
7
{-# OPTIONS_HADDOCK hide #-}
8
{-# LANGUAGE StandaloneDeriving #-}
9

10 11 12 13 14
-----------------------------------------------------------------------------
-- |
-- Module      :  GHC.ForeignPtr
-- Copyright   :  (c) The University of Glasgow, 1992-2003
-- License     :  see libraries/base/LICENSE
15
--
16 17 18 19 20
-- Maintainer  :  cvs-ghc@haskell.org
-- Stability   :  internal
-- Portability :  non-portable (GHC extensions)
--
-- GHC's implementation of the 'ForeignPtr' data type.
21
--
22 23 24 25
-----------------------------------------------------------------------------

module GHC.ForeignPtr
  (
Don Stewart's avatar
Don Stewart committed
26
        ForeignPtr(..),
27
        ForeignPtrContents(..),
Don Stewart's avatar
Don Stewart committed
28
        FinalizerPtr,
29
        FinalizerEnvPtr,
Don Stewart's avatar
Don Stewart committed
30 31 32 33 34
        newForeignPtr_,
        mallocForeignPtr,
        mallocPlainForeignPtr,
        mallocForeignPtrBytes,
        mallocPlainForeignPtrBytes,
35 36
        mallocForeignPtrAlignedBytes,
        mallocPlainForeignPtrAlignedBytes,
37 38
        addForeignPtrFinalizer,
        addForeignPtrFinalizerEnv,
Don Stewart's avatar
Don Stewart committed
39 40 41
        touchForeignPtr,
        unsafeForeignPtrToPtr,
        castForeignPtr,
42
        plusForeignPtr,
Don Stewart's avatar
Don Stewart committed
43 44 45
        newConcForeignPtr,
        addForeignPtrConcFinalizer,
        finalizeForeignPtr
46 47 48
  ) where

import Foreign.Storable
49
import Data.Foldable    ( sequence_ )
50

51
import GHC.Show
52
import GHC.Base
53
import GHC.IORef
Don Stewart's avatar
Don Stewart committed
54
import GHC.STRef        ( STRef(..) )
55
import GHC.Ptr          ( Ptr(..), FunPtr(..) )
56 57 58 59 60 61

-- |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
62
-- with /finalizers/. A finalizer is a routine that is invoked when
63 64
-- the Haskell storage manager detects that - within the Haskell heap
-- and stack - there are no more references left that are pointing to
65
-- the 'ForeignPtr'.  Typically, the finalizer will, then, invoke
66 67 68 69 70 71 72
-- 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'.
--
73
data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents
74
        -- The Addr# in the ForeignPtr object is intentionally stored
75
        -- separately from the finalizer. The primary aim of the
76 77 78 79 80 81
        -- 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
Don Stewart's avatar
Don Stewart committed
82 83 84
        -- that touchForeignPtr only has to touch the ForeignPtrContents
        -- object, because that ensures that whatever the finalizer is
        -- attached to is kept alive.
85

86 87
data Finalizers
  = NoFinalizers
88 89
  | CFinalizers (Weak# ())
  | HaskellFinalizers [IO ()]
90

91
data ForeignPtrContents
92 93
  = PlainForeignPtr !(IORef Finalizers)
  | MallocPtr      (MutableByteArray# RealWorld) !(IORef Finalizers)
94
  | PlainPtr       (MutableByteArray# RealWorld)
95

96
-- | @since 2.01
97
instance Eq (ForeignPtr a) where
98
    p == q  =  unsafeForeignPtrToPtr p == unsafeForeignPtrToPtr q
99

100
-- | @since 2.01
101
instance Ord (ForeignPtr a) where
102
    compare p q  =  compare (unsafeForeignPtrToPtr p) (unsafeForeignPtrToPtr q)
103

104
-- | @since 2.01
105
instance Show (ForeignPtr a) where
106
    showsPrec p f = showsPrec p (unsafeForeignPtrToPtr f)
107

108

Simon Marlow's avatar
Simon Marlow committed
109
-- |A finalizer is represented as a pointer to a foreign function that, at
chak's avatar
chak committed
110 111
-- finalisation time, gets as an argument a plain pointer variant of the
-- foreign pointer that the finalizer is associated with.
112
--
113 114
-- Note that the foreign function /must/ use the @ccall@ calling convention.
--
115 116
type FinalizerPtr a        = FunPtr (Ptr a -> IO ())
type FinalizerEnvPtr env a = FunPtr (Ptr env -> Ptr a -> IO ())
chak's avatar
chak committed
117

118 119
newConcForeignPtr :: Ptr a -> IO () -> IO (ForeignPtr a)
--
120 121 122 123 124 125 126
-- ^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.
127
--
128 129 130 131 132 133 134
-- 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.
--
135
newConcForeignPtr p finalizer
136
  = do fObj <- newForeignPtr_ p
137 138 139 140
       addForeignPtrConcFinalizer fObj finalizer
       return fObj

mallocForeignPtr :: Storable a => IO (ForeignPtr a)
ross's avatar
ross committed
141 142
-- ^ Allocate some memory and return a 'ForeignPtr' to it.  The memory
-- will be released automatically when the 'ForeignPtr' is discarded.
143
--
ross's avatar
ross committed
144
-- 'mallocForeignPtr' is equivalent to
145
--
ross's avatar
ross committed
146
-- >    do { p <- malloc; newForeignPtr finalizerFree p }
147
--
ross's avatar
ross committed
148
-- although it may be implemented differently internally: you may not
149
-- assume that the memory returned by 'mallocForeignPtr' has been
ross's avatar
ross committed
150
-- allocated with 'Foreign.Marshal.Alloc.malloc'.
151 152 153 154 155 156 157
--
-- 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 'newForeignPtr'
-- with a finalizer.
158
--
159
mallocForeignPtr = doMalloc undefined
ralf's avatar
ralf committed
160
  where doMalloc :: Storable b => b -> IO (ForeignPtr b)
161
        doMalloc a
Eric Seidel's avatar
Eric Seidel committed
162
          | I# size < 0 = errorWithoutStackTrace "mallocForeignPtr: size must be >= 0"
163
          | otherwise = do
164
          r <- newIORef NoFinalizers
Don Stewart's avatar
Don Stewart committed
165
          IO $ \s ->
Simon Marlow's avatar
Simon Marlow committed
166
            case newAlignedPinnedByteArray# size align s of { (# s', mbarr# #) ->
Ian Lynagh's avatar
Ian Lynagh committed
167 168
             (# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#))
                               (MallocPtr mbarr# r) #)
169
            }
170 171
            where !(I# size)  = sizeOf a
                  !(I# align) = alignment a
172

ross's avatar
ross committed
173 174
-- | This function is similar to 'mallocForeignPtr', except that the
-- size of the memory required is given explicitly as a number of bytes.
175
mallocForeignPtrBytes :: Int -> IO (ForeignPtr a)
176
mallocForeignPtrBytes size | size < 0 =
Eric Seidel's avatar
Eric Seidel committed
177
  errorWithoutStackTrace "mallocForeignPtrBytes: size must be >= 0"
178
mallocForeignPtrBytes (I# size) = do
179
  r <- newIORef NoFinalizers
180
  IO $ \s ->
Ian Lynagh's avatar
Ian Lynagh committed
181 182 183
     case newPinnedByteArray# size s      of { (# s', mbarr# #) ->
       (# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#))
                         (MallocPtr mbarr# r) #)
184 185
     }

186 187 188 189
-- | 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)
Simon Marlow's avatar
Simon Marlow committed
190
mallocForeignPtrAlignedBytes size _align | size < 0 =
Eric Seidel's avatar
Eric Seidel committed
191
  errorWithoutStackTrace "mallocForeignPtrAlignedBytes: size must be >= 0"
Simon Marlow's avatar
Simon Marlow committed
192
mallocForeignPtrAlignedBytes (I# size) (I# align) = do
193
  r <- newIORef NoFinalizers
194
  IO $ \s ->
Simon Marlow's avatar
Simon Marlow committed
195
     case newAlignedPinnedByteArray# size align s of { (# s', mbarr# #) ->
196 197 198 199
       (# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#))
                         (MallocPtr mbarr# r) #)
     }

200 201 202 203 204 205 206 207 208 209 210
-- | 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
211
-- finalize such a pointer, will throw an exception.
212
--
213 214 215
mallocPlainForeignPtr :: Storable a => IO (ForeignPtr a)
mallocPlainForeignPtr = doMalloc undefined
  where doMalloc :: Storable b => b -> IO (ForeignPtr b)
216
        doMalloc a
Eric Seidel's avatar
Eric Seidel committed
217
          | I# size < 0 = errorWithoutStackTrace "mallocForeignPtr: size must be >= 0"
218
          | otherwise = IO $ \s ->
Simon Marlow's avatar
Simon Marlow committed
219
            case newAlignedPinnedByteArray# size align s of { (# s', mbarr# #) ->
Ian Lynagh's avatar
Ian Lynagh committed
220 221
             (# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#))
                               (PlainPtr mbarr#) #)
222
            }
223 224
            where !(I# size)  = sizeOf a
                  !(I# align) = alignment a
225 226 227

-- | This function is similar to 'mallocForeignPtrBytes', except that
-- the internally an optimised ForeignPtr representation with no
228 229
-- finalizer is used. Attempts to add a finalizer will cause an
-- exception to be thrown.
230
mallocPlainForeignPtrBytes :: Int -> IO (ForeignPtr a)
231
mallocPlainForeignPtrBytes size | size < 0 =
Eric Seidel's avatar
Eric Seidel committed
232
  errorWithoutStackTrace "mallocPlainForeignPtrBytes: size must be >= 0"
233
mallocPlainForeignPtrBytes (I# size) = IO $ \s ->
Ian Lynagh's avatar
Ian Lynagh committed
234 235 236
    case newPinnedByteArray# size s      of { (# s', mbarr# #) ->
       (# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#))
                         (PlainPtr mbarr#) #)
237 238
     }

239 240 241 242 243
-- | 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)
Simon Marlow's avatar
Simon Marlow committed
244
mallocPlainForeignPtrAlignedBytes size _align | size < 0 =
Eric Seidel's avatar
Eric Seidel committed
245
  errorWithoutStackTrace "mallocPlainForeignPtrAlignedBytes: size must be >= 0"
Simon Marlow's avatar
Simon Marlow committed
246 247
mallocPlainForeignPtrAlignedBytes (I# size) (I# align) = IO $ \s ->
    case newAlignedPinnedByteArray# size align s of { (# s', mbarr# #) ->
248 249 250 251
       (# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#))
                         (PlainPtr mbarr#) #)
     }

ross's avatar
ross committed
252
addForeignPtrFinalizer :: FinalizerPtr a -> ForeignPtr a -> IO ()
253
-- ^This function adds a finalizer to the given foreign object.  The
254 255
-- finalizer will run /before/ all other finalizers for the same
-- object which have already been registered.
256
addForeignPtrFinalizer (FunPtr fp) (ForeignPtr p c) = case c of
257 258
  PlainForeignPtr r -> insertCFinalizer r fp 0# nullAddr# p ()
  MallocPtr     _ r -> insertCFinalizer r fp 0# nullAddr# p c
Eric Seidel's avatar
Eric Seidel committed
259
  _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer"
260 261 262 263 264 265 266 267 268

-- 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.
269 270 271

addForeignPtrFinalizerEnv ::
  FinalizerEnvPtr env a -> Ptr env -> ForeignPtr a -> IO ()
Simon Marlow's avatar
Simon Marlow committed
272
-- ^ Like 'addForeignPtrFinalizerEnv' but allows the finalizer to be
273 274 275 276
-- 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 (FunPtr fp) (Ptr ep) (ForeignPtr p c) = case c of
277 278
  PlainForeignPtr r -> insertCFinalizer r fp 1# ep p ()
  MallocPtr     _ r -> insertCFinalizer r fp 1# ep p c
Eric Seidel's avatar
Eric Seidel committed
279
  _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer"
280 281

addForeignPtrConcFinalizer :: ForeignPtr a -> IO () -> IO ()
282
-- ^This function adds a finalizer to the given @ForeignPtr@.  The
283 284 285 286 287 288 289
-- 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.
--
290 291 292 293 294 295
-- 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, 'Handle's
-- are finalized objects, so a finalizer should not refer to a 'Handle'
-- (including @stdout@, @stdin@ or @stderr@).
--
296
addForeignPtrConcFinalizer (ForeignPtr _ c) finalizer =
297 298
  addForeignPtrConcFinalizer_ c finalizer

Ian Lynagh's avatar
Ian Lynagh committed
299 300
addForeignPtrConcFinalizer_ :: ForeignPtrContents -> IO () -> IO ()
addForeignPtrConcFinalizer_ (PlainForeignPtr r) finalizer = do
301
  noFinalizers <- insertHaskellFinalizer r finalizer
302
  if noFinalizers
303
     then IO $ \s ->
Don Stewart's avatar
Don Stewart committed
304
              case r of { IORef (STRef r#) ->
305 306
              case mkWeak# r# () (unIO $ foreignPtrFinalizer r) s of {
                (# s1, _ #) -> (# s1, () #) }}
307
     else return ()
308
addForeignPtrConcFinalizer_ f@(MallocPtr fo r) finalizer = do
309
  noFinalizers <- insertHaskellFinalizer r finalizer
310
  if noFinalizers
311
     then  IO $ \s ->
312
               case mkWeak# fo () finalizer' s of
Ian Lynagh's avatar
Ian Lynagh committed
313
                  (# s1, _ #) -> (# s1, () #)
314
     else return ()
315
  where
316 317
    finalizer' :: State# RealWorld -> (# State# RealWorld, () #)
    finalizer' = unIO (foreignPtrFinalizer r >> touch f)
318

319
addForeignPtrConcFinalizer_ _ _ =
Eric Seidel's avatar
Eric Seidel committed
320
  errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to plain pointer"
321

322 323 324 325 326 327 328 329 330 331 332 333
insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool
insertHaskellFinalizer r f = do
  !wasEmpty <- atomicModifyIORef r $ \finalizers -> case finalizers of
      NoFinalizers -> (HaskellFinalizers [f], True)
      HaskellFinalizers fs -> (HaskellFinalizers (f:fs), False)
      _ -> noMixingError
  return wasEmpty

-- | A box around Weak#, private to this module.
data MyWeak = MyWeak (Weak# ())

insertCFinalizer ::
334 335 336
  IORef Finalizers -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
insertCFinalizer r fp flag ep p val = do
  MyWeak w <- ensureCFinalizerWeak r val
337 338 339 340 341 342 343
  IO $ \s -> case addCFinalizerToWeak# fp p flag ep w s of
      (# s1, 1# #) -> (# 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#.
344
      (# s1, _ #) -> unIO (insertCFinalizer r fp flag ep p val) s1
345

346 347
ensureCFinalizerWeak :: IORef Finalizers -> value -> IO MyWeak
ensureCFinalizerWeak ref@(IORef (STRef r#)) value = do
348 349 350 351 352
  fin <- readIORef ref
  case fin of
      CFinalizers weak -> return (MyWeak weak)
      HaskellFinalizers{} -> noMixingError
      NoFinalizers -> IO $ \s ->
353 354
          case mkWeakNoFinalizer# r# (unsafeCoerce# value) s of { (# s1, w #) ->
             -- See Note [MallocPtr finalizers] (#10904)
355 356 357 358 359 360 361 362 363 364 365 366
          case atomicModifyMutVar# r# (update w) s1 of
              { (# s2, (weak, needKill ) #) ->
          if needKill
            then case finalizeWeak# w s2 of { (# s3, _, _ #) ->
              (# s3, weak #) }
            else (# s2, weak #) }}
  where
      update _ fin@(CFinalizers w) = (fin, (MyWeak w, True))
      update w NoFinalizers = (CFinalizers w, (MyWeak w, False))
      update _ _ = noMixingError

noMixingError :: a
Eric Seidel's avatar
Eric Seidel committed
367
noMixingError = errorWithoutStackTrace $
368 369 370 371
   "GHC.ForeignPtr: attempt to mix Haskell and C finalizers " ++
   "in the same ForeignPtr"

foreignPtrFinalizer :: IORef Finalizers -> IO ()
372
foreignPtrFinalizer r = do
373 374 375 376
  fs <- atomicModifyIORef r $ \fs -> (NoFinalizers, fs) -- atomic, see #7170
  case fs of
    NoFinalizers -> return ()
    CFinalizers w -> IO $ \s -> case finalizeWeak# w s of
377
        (# s1, 1#, f #) -> f s1
378 379
        (# s1, _, _ #) -> (# s1, () #)
    HaskellFinalizers actions -> sequence_ actions
380

381 382 383
newForeignPtr_ :: Ptr a -> IO (ForeignPtr a)
-- ^Turns a plain memory reference into a foreign pointer that may be
-- associated with finalizers by using 'addForeignPtrFinalizer'.
384
newForeignPtr_ (Ptr obj) =  do
385
  r <- newIORef NoFinalizers
386
  return (ForeignPtr obj (PlainForeignPtr r))
387

388 389 390
touchForeignPtr :: ForeignPtr a -> IO ()
-- ^This function ensures that the foreign object in
-- question is alive at the given place in the sequence of IO
ross's avatar
ross committed
391
-- actions. In particular 'Foreign.ForeignPtr.withForeignPtr'
392 393
-- does a 'touchForeignPtr' after it
-- executes the user action.
394
--
395 396
-- Note that this function should not be used to express dependencies
-- between finalizers on 'ForeignPtr's.  For example, if the finalizer
397 398 399 400 401 402 403 404 405 406 407 408 409
-- 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
410 411
-- result in artificial deadlock.  Another alternative is to use
-- explicit reference counting.
412
--
Ian Lynagh's avatar
Ian Lynagh committed
413
touchForeignPtr (ForeignPtr _ r) = touch r
414

Ian Lynagh's avatar
Ian Lynagh committed
415 416
touch :: ForeignPtrContents -> IO ()
touch r = IO $ \s -> case touch# r s of s' -> (# s', () #)
417

418
unsafeForeignPtrToPtr :: ForeignPtr a -> Ptr a
419 420
-- ^This function extracts the pointer component of a foreign
-- pointer.  This is a potentially dangerous operations, as if the
421
-- argument to 'unsafeForeignPtrToPtr' is the last usage
422
-- occurrence of the given foreign pointer, then its finalizer(s) will
423 424 425 426 427 428
-- 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
ross's avatar
ross committed
429
-- should preferably use 'Foreign.ForeignPtr.withForeignPtr' rather
430
-- than combinations of 'unsafeForeignPtrToPtr' and
Simon Marlow's avatar
Simon Marlow committed
431
-- 'touchForeignPtr'.  However, the latter routines
432
-- are occasionally preferred in tool generated marshalling code.
Ian Lynagh's avatar
Ian Lynagh committed
433
unsafeForeignPtrToPtr (ForeignPtr fo _) = Ptr fo
434 435 436 437

castForeignPtr :: ForeignPtr a -> ForeignPtr b
-- ^This function casts a 'ForeignPtr'
-- parameterised by one type into another type.
438
castForeignPtr = coerce
439

440 441 442
plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b
-- ^Advances the given address by the given offset in bytes.
--
443 444 445 446 447 448 449 450
-- 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.
--
451 452 453
-- @since 4.10.0.0
plusForeignPtr (ForeignPtr addr c) (I# d) = ForeignPtr (plusAddr# addr d) c

dons's avatar
dons committed
454
-- | Causes the finalizers associated with a foreign pointer to be run
455 456
-- immediately.
finalizeForeignPtr :: ForeignPtr a -> IO ()
457
finalizeForeignPtr (ForeignPtr _ (PlainPtr _)) = return () -- no effect
458
finalizeForeignPtr (ForeignPtr _ foreignPtr) = foreignPtrFinalizer refFinalizers
Don Stewart's avatar
Don Stewart committed
459 460 461 462
        where
                refFinalizers = case foreignPtr of
                        (PlainForeignPtr ref) -> ref
                        (MallocPtr     _ ref) -> ref
Ian Lynagh's avatar
Ian Lynagh committed
463
                        PlainPtr _            ->
Eric Seidel's avatar
Eric Seidel committed
464
                            errorWithoutStackTrace "finalizeForeignPtr PlainPtr"
465