1 ! Copyright (C) 2007, 2010 Doug Coleman, Slava Pestov.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs continuations kernel namespaces
9 ERROR: already-unregistered disposable ;
17 : register-disposable ( obj -- )
18 debug-leaks? get-global [ current-continuation >>continuation ] when
19 disposables get adjoin ;
21 : unregister-disposable ( obj -- )
22 dup disposables get ?delete [ drop ] [ already-unregistered ] if ;
26 TUPLE: disposable < identity-tuple
30 : new-disposable ( class -- disposable )
31 new dup register-disposable ; inline
33 GENERIC: dispose* ( disposable -- )
35 ERROR: already-disposed disposable ;
37 : check-disposed ( disposable -- disposable )
38 dup disposed>> [ already-disposed ] when ; inline
40 : if-disposed ( ..a disposable quot1: ( ..a -- ..b ) quot2: ( ..a disposable -- ..b ) -- ..b )
41 [ dup disposed>> ] [ [ drop ] prepose ] [ ] tri* if ; inline
43 : when-disposed ( ..a disposable quot1: ( ..a -- ..b ) quot2: ( ..a disposable -- ..b ) -- ..b )
44 [ ] if-disposed ; inline
46 : unless-disposed ( ... disposable quot: ( ... disposable -- ... ) -- ... )
47 [ ] swap if-disposed ; inline
49 GENERIC: dispose ( disposable -- )
51 M: object dispose [ t >>disposed dispose* ] unless-disposed ;
55 [ unregister-disposable ]
60 : dispose-to ( obj accum -- )
61 [ dispose ] [ push ] bi-curry* recover ; inline
63 : dispose-each ( seq -- )
64 V{ } clone [ [ dispose-to ] curry each ] keep
65 [ last rethrow ] unless-empty ;
67 : with-disposal ( object quot -- )
68 over [ dispose ] curry finally ; inline
72 SYMBOL: always-destructors
74 SYMBOL: error-destructors
76 : do-always-destructors ( -- )
77 always-destructors get <reversed> dispose-each ;
79 : do-error-destructors ( -- )
80 error-destructors get <reversed> dispose-each ;
84 : &dispose ( disposable -- disposable )
85 dup always-destructors get push ; inline
87 : |dispose ( disposable -- disposable )
88 dup error-destructors get push ; inline
90 : with-destructors ( quot -- )
92 V{ } clone always-destructors pick set-at
93 V{ } clone error-destructors pick set-at [
94 [ do-always-destructors ]
95 [ do-error-destructors ]
97 ] with-variables ; inline
100 HS{ } clone disposables set-global
101 V{ } clone always-destructors set-global
102 V{ } clone error-destructors set-global
106 do-always-destructors