-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoink.hs
67 lines (52 loc) · 2.32 KB
/
oink.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE TypeApplications #-}
import Control.Concurrent (threadDelay)
import Data.Function ((&))
import Data.IORef (newIORef, readIORef)
import ErsatzPointer qualified as Ersatz (Pointer (Pointer))
import ErsatzPointer qualified as ErsatzPointer
import System.Mem (performGC)
main :: IO ()
main = do
source <- newIORef ()
let target = 17 :: Int
-- Construct an ersatz pointer made of straw from source to target.
strawPointerReference <-
ErsatzPointer.construct @'ErsatzPointer.Straw $
Ersatz.Pointer source target
& ErsatzPointer.onDemolish (putStrLn "Goodbye, straw world!")
let queryStrawPointer =
ErsatzPointer.dereference strawPointerReference >>= \case
Nothing -> putStrLn "Straw pointer is no longer constructed."
Just (Ersatz.Pointer _source _target) -> putStrLn "Straw pointer is still constructed."
-- Construct an ersatz pointer made of brick from source to target.
brickPointerReference <-
ErsatzPointer.construct @'ErsatzPointer.Brick $
Ersatz.Pointer source target
& ErsatzPointer.onDemolish (putStrLn "Goodbye, brick world!")
let queryBrickPointer =
ErsatzPointer.dereference brickPointerReference >>= \case
Nothing -> putStrLn "Brick pointer is no longer constructed."
Just (Ersatz.Pointer _source _target) -> putStrLn "Brick pointer is still constructed."
-- Query whether the straw pointer is still constructed.
queryStrawPointer
-- Query whether the brick pointer is still constructed.
queryBrickPointer
-- Demolish the straw pointer before the source is garbage-collected, and observe that its finalizer runs.
ErsatzPointer.demolish strawPointerReference
-- Query whether the straw pointer is still constructed.
queryStrawPointer
-- Observe that a second demolish is a no-op: its finalizer does not run again.
ErsatzPointer.demolish strawPointerReference
-- Keep the source alive until here.
readIORef source
-- Run a major GC and observe that the brick pointer finalizer runs.
putStrLn "Running performGC"
performGC
-- Sleep for 100ms just to allow finalizer to run.
threadDelay 100_000
-- Query whether the brick pointer is still constructed.
queryBrickPointer