Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- data a :=> b where
- establish :: (a :=> b) -> IO (a :=>? b)
- establish_ :: (a :=> b) -> IO ()
- onDismantle :: (a :=> b) -> IO () -> a :=> b
- data a :=>? b
- dereference :: (a :=>? b) -> IO (Maybe (a :=> b))
- dismantle :: (a :=>? b) -> IO ()
- class Source a where
- primitiveIdentity :: a -> PrimitiveIdentity
- data PrimitiveIdentity
Ersatz pointer
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
andb
such that ifa
is still alive, thenb
is too, exactly as ifa
contained an actual pointer tob
, 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 whetherp
is still established, which will be the case until eithera
is garbage-collected, orp
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 tob
.a
andb
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 tob
.a
andb
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
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, becausea
(and thereforeb
) are still alive.
┌ Memory ───┐ │ a ──p─➤ b │ │ ⇡ │ │ r │ └───────────┘
p
was dismantled becausea
was garbage-collected; it is unknown whetherb
is still alive, becauseb
may still be referred to by another object.
┌ Memory ───┐ │ ? │ │ ⇡ │ │ r │ └───────────┘
p
was dismantled explicitly; it is unknown whethera
is still alive, and whetherb
is still alive.
┌ Memory ───┐ │ ? ? │ │ ⇡ │ │ r │ └───────────┘
dismantle :: (a :=>? b) -> IO () Source #
Dismantle an ersatz pointer p
from a
to b
, which
- Undoes the relationship established by
establish
, i.e. makes it no longer the case that ifa
is alive,b
is too. - 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
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
data MyRecord = MyRecord { ... , ref :: IORef () , ... } instanceSource
MyRecord whereprimitiveIdentity
MyRecord{ref} =primitiveIdentity
ref
primitiveIdentity :: a -> PrimitiveIdentity Source #
Instances
Source (TVar a) Source # | |
Defined in ErsatzPointer primitiveIdentity :: TVar a -> PrimitiveIdentity Source # | |
Source (IORef a) Source # | |
Defined in ErsatzPointer primitiveIdentity :: IORef a -> PrimitiveIdentity Source # | |
Source (MVar a) Source # | |
Defined in ErsatzPointer primitiveIdentity :: MVar a -> PrimitiveIdentity Source # |
data PrimitiveIdentity Source #
The primitive identity of a value.