vocabs.refresh.monitor: spin off new monitor threads when add-vocab-root is called. Fixes a problem where depending on the order of startup hooks, refresh-all would sometimes be broken for custom vocab roots

db4
Slava Pestov 2010-05-31 20:14:07 -04:00
parent d8ce35aacc
commit f78bbb865e
2 changed files with 72 additions and 66 deletions

View File

@ -1,59 +1,58 @@
! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs command-line concurrency.messaging
continuations init io.backend io.files io.monitors io.pathnames
kernel namespaces sequences sets splitting threads
tr vocabs vocabs.loader vocabs.refresh vocabs.cache ;
IN: vocabs.refresh.monitor
TR: convert-separators "/\\" ".." ;
: vocab-dir>vocab-name ( path -- vocab )
trim-head-separators
trim-tail-separators
convert-separators ;
: path>vocab-name ( path -- vocab )
dup ".factor" tail? [ parent-directory ] when ;
: chop-vocab-root ( path -- path' )
"resource:" prepend-path normalize-path
dup vocab-roots get
[ normalize-path ] map
[ head? ] with find nip
?head drop ;
: path>vocab ( path -- vocab )
chop-vocab-root path>vocab-name vocab-dir>vocab-name ;
: monitor-loop ( -- )
#! On OS X, monitors give us the full path, so we chop it
#! off if its there.
receive path>> path>vocab changed-vocab
reset-cache
monitor-loop ;
: add-monitor-for-path ( path -- )
dup exists? [ t my-mailbox (monitor) ] when drop ;
: monitor-thread ( -- )
[
[
vocab-roots get [ add-monitor-for-path ] each
H{ } clone changed-vocabs set-global
vocabs [ changed-vocab ] each
monitor-loop
] with-monitors
] ignore-errors ;
: start-monitor-thread ( -- )
#! Silently ignore errors during monitor creation since
#! monitors are not supported on all platforms.
[ monitor-thread ] "Vocabulary monitor" spawn drop ;
[
"-no-monitors" (command-line) member?
[ start-monitor-thread ] unless
] "vocabs.refresh.monitor" add-startup-hook
! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs command-line concurrency.messaging
continuations init io.backend io.files io.monitors io.pathnames
kernel namespaces sequences sets splitting threads fry
tr vocabs vocabs.loader vocabs.refresh vocabs.cache ;
IN: vocabs.refresh.monitor
TR: convert-separators "/\\" ".." ;
: vocab-dir>vocab-name ( path -- vocab )
trim-head-separators
trim-tail-separators
convert-separators ;
: path>vocab-name ( path -- vocab )
dup ".factor" tail? [ parent-directory ] when ;
: chop-vocab-root ( path -- path' )
"resource:" prepend-path normalize-path
dup vocab-roots get
[ normalize-path ] map
[ head? ] with find nip
?head drop ;
: path>vocab ( path -- vocab )
chop-vocab-root path>vocab-name vocab-dir>vocab-name ;
: monitor-loop ( monitor -- )
#! On OS X, monitors give us the full path, so we chop it
#! off if its there.
[ next-change path>> path>vocab changed-vocab reset-cache ]
[ monitor-loop ]
bi ;
: (start-vocab-monitor) ( vocab-root -- )
dup exists?
[ [ t <monitor> monitor-loop ] with-monitors ] [ drop ] if ;
: start-vocab-monitor ( vocab-root -- )
[ '[ [ _ (start-vocab-monitor) ] ignore-errors ] ]
[ "Root monitor: " prepend ]
bi spawn drop ;
: init-vocab-monitor ( -- )
H{ } clone changed-vocabs set-global
vocabs [ changed-vocab ] each ;
[
"-no-monitors" (command-line) member? [
[ drop ] add-vocab-root-hook set-global
f changed-vocabs set-global
] [
init-vocab-monitor
vocab-roots get [ start-vocab-monitor ] each
[ start-vocab-monitor ] add-vocab-root-hook set-global
] if
] "vocabs.refresh.monitor" add-startup-hook

View File

@ -8,15 +8,22 @@ IN: vocabs.loader
SYMBOL: vocab-roots
V{
"resource:core"
"resource:basis"
"resource:extra"
"resource:work"
} clone vocab-roots set-global
SYMBOL: add-vocab-root-hook
[
V{
"resource:core"
"resource:basis"
"resource:extra"
"resource:work"
} clone vocab-roots set-global
[ drop ] add-vocab-root-hook set-global
] "vocabs.loader" add-startup-hook
: add-vocab-root ( root -- )
vocab-roots get adjoin ;
[ vocab-roots get adjoin ]
[ add-vocab-root-hook get-global call( root -- ) ] bi ;
SYMBOL: root-cache