diff --git a/basis/listener/listener.factor b/basis/listener/listener.factor index 34d9eac121..57d1fd3964 100644 --- a/basis/listener/listener.factor +++ b/basis/listener/listener.factor @@ -163,6 +163,7 @@ SYMBOL: interactive-vocabs "syntax" "tools.annotations" "tools.crossref" + "tools.destructors" "tools.disassembler" "tools.errors" "tools.memory" diff --git a/basis/tools/destructors/destructors-docs.factor b/basis/tools/destructors/destructors-docs.factor index e5a8f0318b..e01c61db00 100644 --- a/basis/tools/destructors/destructors-docs.factor +++ b/basis/tools/destructors/destructors-docs.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: help.markup help.syntax quotations ; +USING: help.markup help.syntax help.tips quotations destructors ; IN: tools.destructors HELP: disposables. @@ -10,10 +10,13 @@ HELP: leaks { $values { "quot" quotation } } -{ $description "Runs a quotation, printing any increases in the number of disposable objects after the quotation returns." } ; +{ $description "Runs a quotation, printing any increases in the number of disposable objects after the quotation returns. The " { $link debug-leaks? } " variable is also switched on while the quotation runs, recording the current continuation in every newly-created disposable object." } ; + +TIP: "Use the " { $link leaks } " combinator to track down resource leaks." ; ARTICLE: "tools.destructors" "Destructor tools" "The " { $vocab-link "tools.destructors" } " vocabulary provides words for tracking down resource leaks." +{ $subsection debug-leaks? } { $subsection disposables. } { $subsection leaks } { $see-also "destructors" } ; diff --git a/basis/tools/destructors/destructors-tests.factor b/basis/tools/destructors/destructors-tests.factor new file mode 100644 index 0000000000..24904f76f6 --- /dev/null +++ b/basis/tools/destructors/destructors-tests.factor @@ -0,0 +1,13 @@ +USING: kernel tools.destructors tools.test destructors namespaces ; +IN: tools.destructors.tests + +f debug-leaks? set-global + +[ [ 3 throw ] leaks ] must-fail + +[ f ] [ debug-leaks? get-global ] unit-test + +[ ] [ [ ] leaks ] unit-test + +[ f ] [ debug-leaks? get-global ] unit-test + diff --git a/basis/tools/destructors/destructors.factor b/basis/tools/destructors/destructors.factor index c0aa35b049..42d09d0ef9 100644 --- a/basis/tools/destructors/destructors.factor +++ b/basis/tools/destructors/destructors.factor @@ -47,5 +47,5 @@ PRIVATE> t debug-leaks? set-global [ [ call disposables get clone ] dip - ] [ ] [ f debug-leaks? set-global ] cleanup + ] [ f debug-leaks? set-global ] [ ] cleanup assoc-diff (disposables.) ; inline diff --git a/core/destructors/destructors-docs.factor b/core/destructors/destructors-docs.factor index 8a0c36b99a..a342352b90 100644 --- a/core/destructors/destructors-docs.factor +++ b/core/destructors/destructors-docs.factor @@ -1,7 +1,24 @@ USING: help.markup help.syntax libc kernel continuations io -sequences ; +sequences classes ; IN: destructors +HELP: debug-leaks? +{ $var-description "When this variable is on, " { $link new-disposable } " stores the current continuation in the " { $link disposable } "'s " { $slot "continuation" } " slot." } +{ $see-also "tools.destructors" } ; + +HELP: disposable +{ $class-description "Parent class for disposable resources. This class has three slots:" + { $list + { { $slot "disposed" } " - boolean. Set to true by " { $link dispose } ". Assert that it is false with " { $link check-disposed } "." } + { { $slot "id" } " - unique identifier. Set by " { $link new-disposable } "." } + { { $slot "continuation" } " - current continuation at construction time, for debugging. Set by " { $link new-disposable } " if " { $link debug-leaks? } " is on." } + } +"New instances must be constructed with " { $link new-disposable } " and subclasses must implement " { $link dispose* } "." } ; + +HELP: new-disposable +{ $values { "class" class } { "disposable" disposable } } +{ $description "Constructs a new instance of a subclass of " { $link disposable } ". This sets the " { $slot "id" } " slot, registers the new object with the global " { $link disposables } " set, and if " { $link debug-leaks? } " is on, stores the current continuation in the " { $slot "continuation" } " slot." } ; + HELP: dispose { $values { "disposable" "a disposable object" } } { $contract "Releases operating system resources associated with a disposable object. Disposable objects include streams, memory mapped files, and so on." @@ -52,7 +69,8 @@ HELP: dispose-each { $description "Attempts to dispose of each element of a sequence and collects all of the errors into a sequence. If any errors are thrown during disposal, the last error is rethrown after all objects have been disposed." } ; HELP: disposables -{ $var-description "Global variable holding all disposable objects which have not been disposed of yet. The " { $link new-disposable } " word adds objects here, and the " { $link dispose } " method on disposables removes them. The " { $link "tools.destructors" } " vocabulary provides some words for working with this data." } ; +{ $var-description "Global variable holding all disposable objects which have not been disposed of yet. The " { $link new-disposable } " word adds objects here, and the " { $link dispose } " method on disposables removes them. The " { $link "tools.destructors" } " vocabulary provides some words for working with this data." } +{ $see-also "tools.destructors" } ; ARTICLE: "destructors-anti-patterns" "Resource disposal anti-patterns" "Words which create objects corresponding to external resources should always be used with " { $link with-disposal } ". The following code is wrong:"