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

db4
Slava Pestov 2010-02-20 00:23:24 +13:00
parent be8a0f7779
commit a343f8a31c
6 changed files with 48 additions and 10 deletions

View File

@ -59,7 +59,9 @@ M: linux-monitor dispose* ( monitor -- )
[ inotify>> handle>> handle-fd ] [ wd>> ] bi [ inotify>> handle>> handle-fd ] [ wd>> ] bi
inotify_rm_watch io-error inotify_rm_watch io-error
] if ] if
] bi ; ]
[ call-next-method ]
tri ;
: ignore-flags? ( mask -- ? ) : ignore-flags? ( mask -- ? )
{ {

View File

@ -1,4 +1,4 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: io.backend io.monitors USING: io.backend io.monitors
core-foundation.fsevents continuations kernel sequences core-foundation.fsevents continuations kernel sequences
@ -16,6 +16,7 @@ M:: macosx (monitor) ( path recursive? mailbox -- monitor )
dup [ enqueue-notifications ] curry dup [ enqueue-notifications ] curry
path 1array 0 0 <event-stream> >>handle ; path 1array 0 0 <event-stream> >>handle ;
M: macosx-monitor dispose* handle>> dispose ; M: macosx-monitor dispose*
[ handle>> dispose ] [ call-next-method ] bi ;
macosx set-io-backend macosx set-io-backend

View File

@ -3,7 +3,7 @@ USING: io.monitors tools.test io.files system sequences
continuations namespaces concurrency.count-downs kernel io continuations namespaces concurrency.count-downs kernel io
threads calendar prettyprint destructors io.timeouts threads calendar prettyprint destructors io.timeouts
io.files.temp io.directories io.directories.hierarchy io.files.temp io.directories io.directories.hierarchy
io.pathnames accessors ; io.pathnames accessors concurrency.promises ;
os { winnt linux macosx } member? [ os { winnt linux macosx } member? [
[ [
@ -110,4 +110,23 @@ os { winnt linux macosx } member? [
[ [ t ] [ "m" get next-change drop ] while ] must-fail [ [ t ] [ "m" get next-change drop ] while ] must-fail
[ ] [ "m" get dispose ] unit-test [ ] [ "m" get dispose ] unit-test
] with-monitors ] with-monitors
! Disposing a monitor should throw an error in any threads
! waiting on notifications
[
[ ] [
<promise> "p" set
"monitor-test" temp-file t <monitor> "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 ] when

View File

@ -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. ! See http://factorcode.org/license.txt for BSD license.
USING: io.backend kernel continuations destructors namespaces USING: io.backend kernel continuations destructors namespaces
sequences assocs hashtables sorting arrays threads boxes sequences assocs hashtables sorting arrays threads boxes
@ -26,6 +26,15 @@ M: monitor timeout timeout>> ;
M: monitor set-timeout (>>timeout) ; M: monitor set-timeout (>>timeout) ;
<PRIVATE
SYMBOL: monitor-disposed
PRIVATE>
M: monitor dispose*
[ monitor-disposed ] dip queue>> mailbox-put ;
: new-monitor ( path mailbox class -- monitor ) : new-monitor ( path mailbox class -- monitor )
new-disposable new-disposable
swap >>queue swap >>queue
@ -34,8 +43,11 @@ M: monitor set-timeout (>>timeout) ;
TUPLE: file-change path changed monitor ; TUPLE: file-change path changed monitor ;
: queue-change ( path changes monitor -- ) : queue-change ( path changes monitor -- )
3dup and and 3dup and and [
[ [ file-change boa ] keep queue>> mailbox-put ] [ 3drop ] if ; [ check-disposed ] keep
[ file-change boa ] keep
queue>> mailbox-put
] [ 3drop ] if ;
HOOK: (monitor) io-backend ( path recursive? mailbox -- monitor ) HOOK: (monitor) io-backend ( path recursive? mailbox -- monitor )
@ -43,7 +55,11 @@ HOOK: (monitor) io-backend ( path recursive? mailbox -- monitor )
<mailbox> (monitor) ; <mailbox> (monitor) ;
: next-change ( monitor -- change ) : 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: +add-file+
SYMBOL: +remove-file+ SYMBOL: +remove-file+

View File

@ -41,7 +41,7 @@ DEFER: add-child-monitor
M: recursive-monitor dispose* M: recursive-monitor dispose*
[ "stop" swap thread>> send-synchronous drop ] [ "stop" swap thread>> send-synchronous drop ]
[ queue>> dispose ] [ call-next-method ]
bi ; bi ;
: stop-pump ( -- ) : stop-pump ( -- )

View File

@ -100,4 +100,4 @@ M:: winnt (monitor) ( path recursive? mailbox -- monitor )
] with-destructors ; ] with-destructors ;
M: win32-monitor dispose M: win32-monitor dispose
port>> dispose ; [ port>> dispose ] [ call-next-method ] bi ;