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_rm_watch io-error
] if
] bi ;
]
[ call-next-method ]
tri ;
: 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.
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 <event-stream> >>handle ;
M: macosx-monitor dispose* handle>> dispose ;
M: macosx-monitor dispose*
[ handle>> dispose ] [ call-next-method ] bi ;
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
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
[
[ ] [
<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

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.
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) ;
<PRIVATE
SYMBOL: monitor-disposed
PRIVATE>
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 )
<mailbox> (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+

View File

@ -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 ( -- )

View File

@ -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 ;