From a343f8a31ccf418e39e0a5c5e18a9dfe51034efa Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 20 Feb 2010 00:23:24 +1300 Subject: [PATCH] io.monitors: if a monitor is disposed while other threads are waiting on it, an error will be thrown from next-change, instead of those threads hanging forever. This makes monitors consistent with streams and other native resources that behave in a similar manner --- basis/io/monitors/linux/linux.factor | 4 +++- basis/io/monitors/macosx/macosx.factor | 5 ++-- basis/io/monitors/monitors-tests.factor | 21 ++++++++++++++++- basis/io/monitors/monitors.factor | 24 ++++++++++++++++---- basis/io/monitors/recursive/recursive.factor | 2 +- basis/io/monitors/windows/nt/nt.factor | 2 +- 6 files changed, 48 insertions(+), 10 deletions(-) diff --git a/basis/io/monitors/linux/linux.factor b/basis/io/monitors/linux/linux.factor index 7653eaa84c..eacc920303 100644 --- a/basis/io/monitors/linux/linux.factor +++ b/basis/io/monitors/linux/linux.factor @@ -59,7 +59,9 @@ M: linux-monitor dispose* ( monitor -- ) [ inotify>> handle>> handle-fd ] [ wd>> ] bi inotify_rm_watch io-error ] if - ] bi ; + ] + [ call-next-method ] + tri ; : ignore-flags? ( mask -- ? ) { diff --git a/basis/io/monitors/macosx/macosx.factor b/basis/io/monitors/macosx/macosx.factor index e71fb2eca2..dbbbe7c7e3 100644 --- a/basis/io/monitors/macosx/macosx.factor +++ b/basis/io/monitors/macosx/macosx.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2008 Slava Pestov. +! Copyright (C) 2008, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: io.backend io.monitors core-foundation.fsevents continuations kernel sequences @@ -16,6 +16,7 @@ M:: macosx (monitor) ( path recursive? mailbox -- monitor ) dup [ enqueue-notifications ] curry path 1array 0 0 >>handle ; -M: macosx-monitor dispose* handle>> dispose ; +M: macosx-monitor dispose* + [ handle>> dispose ] [ call-next-method ] bi ; macosx set-io-backend diff --git a/basis/io/monitors/monitors-tests.factor b/basis/io/monitors/monitors-tests.factor index 576ac7ca30..ac17c4a39f 100644 --- a/basis/io/monitors/monitors-tests.factor +++ b/basis/io/monitors/monitors-tests.factor @@ -3,7 +3,7 @@ USING: io.monitors tools.test io.files system sequences continuations namespaces concurrency.count-downs kernel io threads calendar prettyprint destructors io.timeouts io.files.temp io.directories io.directories.hierarchy -io.pathnames accessors ; +io.pathnames accessors concurrency.promises ; os { winnt linux macosx } member? [ [ @@ -110,4 +110,23 @@ os { winnt linux macosx } member? [ [ [ t ] [ "m" get next-change drop ] while ] must-fail [ ] [ "m" get dispose ] unit-test ] with-monitors + + ! Disposing a monitor should throw an error in any threads + ! waiting on notifications + [ + [ ] [ + "p" set + "monitor-test" temp-file t "m" set + 10 seconds "m" get set-timeout + ] unit-test + + [ + [ "m" get next-change ] [ ] recover + "p" get fulfill + ] in-thread + + [ ] [ 1 seconds sleep ] unit-test + [ ] [ "m" get dispose ] unit-test + [ t ] [ "p" get 10 seconds ?promise-timeout already-disposed? ] unit-test + ] with-monitors ] when diff --git a/basis/io/monitors/monitors.factor b/basis/io/monitors/monitors.factor index cb2f552a32..731798c424 100644 --- a/basis/io/monitors/monitors.factor +++ b/basis/io/monitors/monitors.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2008, 2009 Slava Pestov. +! Copyright (C) 2008, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: io.backend kernel continuations destructors namespaces sequences assocs hashtables sorting arrays threads boxes @@ -26,6 +26,15 @@ M: monitor timeout timeout>> ; M: monitor set-timeout (>>timeout) ; + + +M: monitor dispose* + [ monitor-disposed ] dip queue>> mailbox-put ; + : new-monitor ( path mailbox class -- monitor ) new-disposable swap >>queue @@ -34,8 +43,11 @@ M: monitor set-timeout (>>timeout) ; TUPLE: file-change path changed monitor ; : queue-change ( path changes monitor -- ) - 3dup and and - [ [ file-change boa ] keep queue>> mailbox-put ] [ 3drop ] if ; + 3dup and and [ + [ check-disposed ] keep + [ file-change boa ] keep + queue>> mailbox-put + ] [ 3drop ] if ; HOOK: (monitor) io-backend ( path recursive? mailbox -- monitor ) @@ -43,7 +55,11 @@ HOOK: (monitor) io-backend ( path recursive? mailbox -- monitor ) (monitor) ; : next-change ( monitor -- change ) - [ queue>> ] [ timeout ] bi mailbox-get-timeout ; + [ check-disposed ] + [ + [ ] [ queue>> ] [ timeout ] tri mailbox-get-timeout + dup monitor-disposed eq? [ drop already-disposed ] [ nip ] if + ] bi ; SYMBOL: +add-file+ SYMBOL: +remove-file+ diff --git a/basis/io/monitors/recursive/recursive.factor b/basis/io/monitors/recursive/recursive.factor index 33477abdb6..83c088e882 100644 --- a/basis/io/monitors/recursive/recursive.factor +++ b/basis/io/monitors/recursive/recursive.factor @@ -41,7 +41,7 @@ DEFER: add-child-monitor M: recursive-monitor dispose* [ "stop" swap thread>> send-synchronous drop ] - [ queue>> dispose ] + [ call-next-method ] bi ; : stop-pump ( -- ) diff --git a/basis/io/monitors/windows/nt/nt.factor b/basis/io/monitors/windows/nt/nt.factor index 9cd8bc4df8..4d061cbb1a 100644 --- a/basis/io/monitors/windows/nt/nt.factor +++ b/basis/io/monitors/windows/nt/nt.factor @@ -100,4 +100,4 @@ M:: winnt (monitor) ( path recursive? mailbox -- monitor ) ] with-destructors ; M: win32-monitor dispose - port>> dispose ; + [ port>> dispose ] [ call-next-method ] bi ;