Cleaning up monitors in preparation for Linux inotify

db4
Slava Pestov 2008-02-02 16:23:04 -06:00
parent 70b685fad8
commit ff40513165
3 changed files with 53 additions and 35 deletions

View File

@ -1,11 +1,39 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008 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 ; USING: io.backend kernel continuations namespaces sequences
assocs hashtables sorting arrays ;
IN: io.monitor IN: io.monitor
<PRIVATE
TUPLE: monitor queue closed? ;
: check-monitor ( monitor -- )
monitor-closed? [ "Monitor closed" throw ] when ;
: (monitor) ( delegate -- monitor )
H{ } clone {
set-delegate
set-monitor-queue
} monitor construct ;
HOOK: fill-queue io-backend ( monitor -- assoc )
: changed-file ( changed path -- )
namespace [ swap add ] change-at ;
: dequeue-change ( assoc -- path changes )
delete-any prune natural-sort >array ;
PRIVATE>
HOOK: <monitor> io-backend ( path recursive? -- monitor ) HOOK: <monitor> io-backend ( path recursive? -- monitor )
HOOK: next-change io-backend ( monitor -- path changes ) : next-change ( monitor -- path changed )
dup check-monitor
dup monitor-queue dup assoc-empty? [
drop dup fill-queue over set-monitor-queue next-change
] [ nip dequeue-change ] if ;
SYMBOL: +add-file+ SYMBOL: +add-file+
SYMBOL: +remove-file+ SYMBOL: +remove-file+

View File

@ -14,9 +14,9 @@ TUPLE: io-task port callbacks ;
: io-task-fd io-task-port port-handle ; : io-task-fd io-task-port port-handle ;
: <io-task> ( port continuation class -- task ) : <io-task> ( port continuation/f class -- task )
>r 1vector io-task construct-boa r> construct-delegate ; >r [ 1vector ] [ V{ } clone ] if* io-task construct-boa
inline r> construct-delegate ; inline
TUPLE: input-task ; TUPLE: input-task ;
@ -194,7 +194,7 @@ TUPLE: mx-port mx ;
TUPLE: mx-task ; TUPLE: mx-task ;
: <mx-task> ( port -- task ) : <mx-task> ( port -- task )
f io-task construct-boa mx-task construct-delegate ; f mx-task <io-task> ;
M: mx-task do-io-task M: mx-task do-io-task
io-task-port mx-port-mx 0 swap wait-for-events f ; io-task-port mx-port-mx 0 swap wait-for-events f ;

View File

@ -3,12 +3,10 @@
USING: alien.c-types destructors io.windows USING: alien.c-types destructors io.windows
io.windows.nt.backend kernel math windows windows.kernel32 io.windows.nt.backend kernel math windows windows.kernel32
windows.types libc assocs alien namespaces continuations windows.types libc assocs alien namespaces continuations
io.monitor io.nonblocking io.buffers io.files io sequences io.monitor io.monitor.private io.nonblocking io.buffers io.files
hashtables sorting arrays combinators ; io sequences hashtables sorting arrays combinators ;
IN: io.windows.nt.monitor IN: io.windows.nt.monitor
TUPLE: monitor path recursive? queue closed? ;
: open-directory ( path -- handle ) : open-directory ( path -- handle )
FILE_LIST_DIRECTORY FILE_LIST_DIRECTORY
share-mode share-mode
@ -22,23 +20,26 @@ TUPLE: monitor path recursive? queue closed? ;
dup add-completion dup add-completion
f <win32-file> ; f <win32-file> ;
TUPLE: win32-monitor path recursive? ;
: <win32-monitor> ( path recursive? port -- monitor )
(monitor) {
set-win32-monitor-path
set-win32-monitor-recursive?
set-delegate
} win32-monitor construct ;
M: windows-nt-io <monitor> ( path recursive? -- monitor ) M: windows-nt-io <monitor> ( path recursive? -- monitor )
[ [
>r dup open-directory monitor <buffered-port> r> { over open-directory win32-monitor <buffered-port>
set-monitor-path <win32-monitor>
set-delegate
set-monitor-recursive?
} monitor construct
] with-destructors ; ] with-destructors ;
: check-closed ( monitor -- )
port-type closed eq? [ "Monitor closed" throw ] when ;
: begin-reading-changes ( monitor -- overlapped ) : begin-reading-changes ( monitor -- overlapped )
dup port-handle win32-file-handle dup port-handle win32-file-handle
over buffer-ptr over buffer-ptr
pick buffer-size pick buffer-size
roll monitor-recursive? 1 0 ? roll win32-monitor-recursive? 1 0 ?
FILE_NOTIFY_CHANGE_ALL FILE_NOTIFY_CHANGE_ALL
0 <uint> 0 <uint>
(make-overlapped) (make-overlapped)
@ -49,6 +50,7 @@ M: windows-nt-io <monitor> ( path recursive? -- monitor )
[ [
dup begin-reading-changes dup begin-reading-changes
swap [ save-callback ] 2keep swap [ save-callback ] 2keep
dup check-monitor ! we may have closed it...
get-overlapped-result get-overlapped-result
] with-port-timeout ] with-port-timeout
] with-destructors ; ] with-destructors ;
@ -63,7 +65,7 @@ M: windows-nt-io <monitor> ( path recursive? -- monitor )
{ [ t ] [ +modify-file+ ] } { [ t ] [ +modify-file+ ] }
} cond nip ; } cond nip ;
: changed-file ( directory buffer -- changed path ) : parse-file-notify ( directory buffer -- changed path )
{ {
FILE_NOTIFY_INFORMATION-FileName FILE_NOTIFY_INFORMATION-FileName
FILE_NOTIFY_INFORMATION-FileNameLength FILE_NOTIFY_INFORMATION-FileNameLength
@ -71,22 +73,10 @@ M: windows-nt-io <monitor> ( path recursive? -- monitor )
} get-slots >r memory>u16-string path+ r> parse-action swap ; } get-slots >r memory>u16-string path+ r> parse-action swap ;
: (changed-files) ( directory buffer -- ) : (changed-files) ( directory buffer -- )
2dup changed-file namespace [ swap add ] change-at 2dup parse-file-notify changed-file
dup FILE_NOTIFY_INFORMATION-NextEntryOffset dup zero? dup FILE_NOTIFY_INFORMATION-NextEntryOffset dup zero?
[ 3drop ] [ swap <displaced-alien> (changed-files) ] if ; [ 3drop ] [ swap <displaced-alien> (changed-files) ] if ;
: changed-files ( directory buffer len -- assoc ) M: windows-nt-io fill-queue ( monitor -- assoc )
dup win32-monitor-path over buffer-ptr rot read-changes
[ zero? [ 2drop ] [ (changed-files) ] if ] H{ } make-assoc ; [ zero? [ 2drop ] [ (changed-files) ] if ] H{ } make-assoc ;
: fill-queue ( monitor -- )
dup monitor-path over buffer-ptr pick read-changes
changed-files
swap set-monitor-queue ;
M: windows-nt-io next-change ( monitor -- path changes )
dup check-closed
dup monitor-queue dup assoc-empty? [
drop dup fill-queue next-change
] [
nip delete-any prune natural-sort >array
] if ;