ersatz-pointer-0.1.0: A friendly interface to weak pointers in GHC
Safe HaskellNone
LanguageHaskell2010

ErsatzPointer

Synopsis

Ersatz pointer

data a :=> b where Source #

An ersatz pointer.

Bundled Patterns

pattern (:=>) :: Source a => a -> b -> a :=> b 

establish :: (a :=> b) -> IO (a :=>? b) Source #

Establish an ersatz pointer p from object a to object b.

When this function is called,

  • A relationship is established between a and b such that if a is still alive, then b is too, exactly as if a contained an actual pointer to b, as in (for example) the relationship between a record and one of its fields.
  • An ersatz pointer reference r is created, and can be used to determine whether p is still established, which will be the case until either a is garbage-collected, or p is dismantled explicitly, whichever comes first.
Memory ───┐
       │ a       b │
       └───────────┘

             ┊
             ▼

┌ Code ────────────────────┐
│ r <- establish (a :=> b) │
└──────────────────────────┘

             ┊
             ▼

       ┌ Memory ───┐
       │ a ──p─➤ b │
       │     ⇡     │
       │     r     │
       └───────────┘

Note that it may be the case that

  • a already cotains an actual pointer to b.
  • a and b are the same object.

In either case, establishing an ersatz pointer from a to b may still be useful, because r can then be used to determine whether a has been garbage-collected, so long as r is not dismantled explicitly.

establish_ :: (a :=> b) -> IO () Source #

Like establish, but does not return the ersatz pointer reference r.

This is not useful if either

  • a already cotains an actual pointer to b.
  • a and b are the same object.

onDismantle :: (a :=> b) -> IO () -> a :=> b Source #

Schedule an IO action to be run when p is dismantled, which is either when a is garbage-collected, or when p is dismantled explicitly, whichever comes first.

Ersatz pointer reference

data a :=>? b Source #

An ersatz pointer reference is a reference to an ersatz pointer, and is evidence that the pointer was established at some point.

dereference :: (a :=>? b) -> IO (Maybe (a :=> b)) Source #

Dereference an ersatz pointer reference r to determine whether the corresponding ersatz pointer p from a to b is still established.

In general, if a and b are different objects, there are three possible cases, only two of which are distinguishable.

  • p is still established, because a (and therefore b) are still alive.
Memory ───┐
│ a ──p─➤ b │
│     ⇡     │
│     r     │
└───────────┘
  • p was dismantled because a was garbage-collected; it is unknown whether b is still alive, because b may still be referred to by another object.
Memory ───┐
│         ? │
│     ⇡     │
│     r     │
└───────────┘
  • p was dismantled explicitly; it is unknown whether a is still alive, and whether b is still alive.
Memory ───┐
│ ?       ? │
│     ⇡     │
│     r     │
└───────────┘

dismantle :: (a :=>? b) -> IO () Source #

Dismantle an ersatz pointer p from a to b, which

  1. Undoes the relationship established by establish, i.e. makes it no longer the case that if a is alive, b is too.
  2. Causes any registered onDismantle actions to be run immediately.

This action is a no-op if p was alread dismantled, either because a was already garbage-collected, or because it was dismantled explicitly.

Memory ───┐
 │ a ──p─➤ b │
 │     ⇡     │
 │     r     │
 └───────────┘

       ┊
       ▼

┌ Code ───────┐
│ dismantle r │
└─────────────┘

       ┊
       ▼

 ┌ Memory ───┐
 │ a       b │
 │     ⇡     │
 │     r     │
 └───────────┘

Source

class Source a where Source #

The class of types that can be used as the source of an ersatz pointer.

This includes types whose values have a primitive identity (IORef, MVar, and TVar), but may also include product types that contain such a type via user-defined instances.

Example user-defined instance

Expand
data MyRecord = MyRecord
  { ...
  , ref :: IORef ()
  , ...
  }

instance Source MyRecord where
  primitiveIdentity MyRecord{ref} = primitiveIdentity ref

Instances

Instances details
Source (TVar a) Source # 
Instance details

Defined in ErsatzPointer

Source (IORef a) Source # 
Instance details

Defined in ErsatzPointer

Source (MVar a) Source # 
Instance details

Defined in ErsatzPointer

data PrimitiveIdentity Source #

The primitive identity of a value.