Less drastic changes
parent
e1336e3da2
commit
9edb5875e3
|
@ -5,8 +5,8 @@ hashtables kernel math namespaces sequences words
|
||||||
inference.state inference.backend inference.dataflow system
|
inference.state inference.backend inference.dataflow system
|
||||||
math.parser classes alien.arrays alien.c-types alien.structs
|
math.parser classes alien.arrays alien.c-types alien.structs
|
||||||
alien.syntax cpu.architecture alien inspector quotations assocs
|
alien.syntax cpu.architecture alien inspector quotations assocs
|
||||||
kernel.private concurrency.threads continuations.private libc
|
kernel.private threads continuations.private libc combinators
|
||||||
combinators compiler.errors continuations ;
|
compiler.errors continuations ;
|
||||||
IN: alien.compiler
|
IN: alien.compiler
|
||||||
|
|
||||||
! Common protocol for alien-invoke/alien-callback/alien-indirect
|
! Common protocol for alien-invoke/alien-callback/alien-indirect
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2007 Slava Pestov.
|
! Copyright (C) 2007 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: alien alien.c-types parser concurrency.threads words
|
USING: alien alien.c-types parser threads words kernel.private
|
||||||
kernel.private kernel ;
|
kernel ;
|
||||||
IN: alien.remote-control
|
IN: alien.remote-control
|
||||||
|
|
||||||
: eval-callback
|
: eval-callback
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
USING: kernel namespaces arrays sequences io inference.backend
|
USING: kernel namespaces arrays sequences io inference.backend
|
||||||
inference.state generator debugger math.parser prettyprint words
|
inference.state generator debugger math.parser prettyprint words
|
||||||
compiler.units continuations vocabs assocs alien.compiler dlists
|
compiler.units continuations vocabs assocs alien.compiler dlists
|
||||||
optimizer definitions math compiler.errors concurrency.threads
|
optimizer definitions math compiler.errors threads graphs
|
||||||
graphs generic ;
|
generic ;
|
||||||
IN: compiler
|
IN: compiler
|
||||||
|
|
||||||
: compiled-usages ( words -- seq )
|
: compiled-usages ( words -- seq )
|
||||||
|
|
|
@ -5,7 +5,7 @@ effects generator.fixup generator.registers generic hashtables
|
||||||
inference inference.backend inference.dataflow io kernel
|
inference inference.backend inference.dataflow io kernel
|
||||||
kernel.private layouts math namespaces optimizer
|
kernel.private layouts math namespaces optimizer
|
||||||
optimizer.specializers prettyprint quotations sequences system
|
optimizer.specializers prettyprint quotations sequences system
|
||||||
concurrency.threads words vectors ;
|
threads words vectors ;
|
||||||
IN: generator
|
IN: generator
|
||||||
|
|
||||||
SYMBOL: compile-queue
|
SYMBOL: compile-queue
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
! 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.
|
||||||
IN: io.thread
|
IN: io.thread
|
||||||
USING: concurrency.threads io.backend namespaces init ;
|
USING: threads io.backend namespaces init ;
|
||||||
|
|
||||||
: io-thread ( -- )
|
: io-thread ( -- )
|
||||||
sleep-time io-multiplex yield io-thread ;
|
sleep-time io-multiplex yield ;
|
||||||
|
|
||||||
: start-io-thread ( -- )
|
: start-io-thread ( -- )
|
||||||
[ io-thread ]
|
[ io-thread t ]
|
||||||
"I/O wait" spawn
|
"I/O wait" spawn-server
|
||||||
\ io-thread set-global ;
|
\ io-thread set-global ;
|
||||||
|
|
||||||
[ start-io-thread ] "io.thread" add-init-hook
|
[ start-io-thread ] "io.thread" add-init-hook
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
USING: help.markup help.syntax kernel kernel.private io
|
USING: help.markup help.syntax kernel kernel.private io
|
||||||
concurrency.threads.private continuations dlists init
|
threads.private continuations dlists init quotations strings
|
||||||
quotations strings assocs heaps ;
|
assocs heaps ;
|
||||||
IN: concurrency.threads
|
IN: threads
|
||||||
|
|
||||||
ARTICLE: "threads-start/stop" "Starting and stopping threads"
|
ARTICLE: "threads-start/stop" "Starting and stopping threads"
|
||||||
"Spawning new threads:"
|
"Spawning new threads:"
|
||||||
|
@ -44,7 +44,7 @@ ARTICLE: "thread-impl" "Thread implementation"
|
||||||
ARTICLE: "threads" "Lightweight co-operative threads"
|
ARTICLE: "threads" "Lightweight co-operative threads"
|
||||||
"Factor supports lightweight co-operative threads implemented on top of continuations. A thread will yield while waiting for I/O operations to complete, or when a yield has been explicitly requested."
|
"Factor supports lightweight co-operative threads implemented on top of continuations. A thread will yield while waiting for I/O operations to complete, or when a yield has been explicitly requested."
|
||||||
$nl
|
$nl
|
||||||
"Words for working with threads are in the " { $vocab-link "concurrency.threads" } " vocabulary."
|
"Words for working with threads are in the " { $vocab-link "threads" } " vocabulary."
|
||||||
{ $subsection "threads-start/stop" }
|
{ $subsection "threads-start/stop" }
|
||||||
{ $subsection "threads-yield" }
|
{ $subsection "threads-yield" }
|
||||||
{ $subsection "thread-state" }
|
{ $subsection "thread-state" }
|
|
@ -1,4 +1,4 @@
|
||||||
USING: namespaces io tools.test concurrency.threads kernel ;
|
USING: namespaces io tools.test threads kernel ;
|
||||||
IN: temporary
|
IN: temporary
|
||||||
|
|
||||||
3 "x" set
|
3 "x" set
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2004, 2008 Slava Pestov.
|
! Copyright (C) 2004, 2008 Slava Pestov.
|
||||||
! Copyright (C) 2005 Mackenzie Straight.
|
! Copyright (C) 2005 Mackenzie Straight.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
IN: concurrency.threads
|
IN: threads
|
||||||
USING: arrays hashtables heaps kernel kernel.private math
|
USING: arrays hashtables heaps kernel kernel.private math
|
||||||
namespaces sequences vectors continuations continuations.private
|
namespaces sequences vectors continuations continuations.private
|
||||||
dlists assocs system combinators debugger prettyprint io init ;
|
dlists assocs system combinators debugger prettyprint io init ;
|
||||||
|
@ -53,6 +53,8 @@ threads global [ H{ } assoc-like ] change-at
|
||||||
|
|
||||||
: set-self ( thread -- ) 40 setenv ; inline
|
: set-self ( thread -- ) 40 setenv ; inline
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
: <thread> ( quot name error-handler -- thread )
|
: <thread> ( quot name error-handler -- thread )
|
||||||
\ thread counter H{ } clone {
|
\ thread counter H{ } clone {
|
||||||
set-thread-quot
|
set-thread-quot
|
||||||
|
@ -62,8 +64,6 @@ threads global [ H{ } assoc-like ] change-at
|
||||||
set-thread-variables
|
set-thread-variables
|
||||||
} \ thread construct ;
|
} \ thread construct ;
|
||||||
|
|
||||||
PRIVATE>
|
|
||||||
|
|
||||||
SYMBOL: run-queue
|
SYMBOL: run-queue
|
||||||
SYMBOL: sleep-queue
|
SYMBOL: sleep-queue
|
||||||
|
|
||||||
|
@ -149,7 +149,13 @@ PRIVATE>
|
||||||
] <thread>
|
] <thread>
|
||||||
[ (spawn) ] keep ;
|
[ (spawn) ] keep ;
|
||||||
|
|
||||||
: in-thread ( quot -- ) "Thread" spawn drop ;
|
: spawn-server ( quot name -- thread )
|
||||||
|
>r [ [ ] [ ] while ] curry r> spawn ;
|
||||||
|
|
||||||
|
: in-thread ( quot -- )
|
||||||
|
>r datastack namestack r>
|
||||||
|
[ >r set-namestack set-datastack r> call ] 3curry
|
||||||
|
"Thread" spawn drop ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
|
@ -169,4 +175,4 @@ thread-error-hook set-global
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
[ init-threads ] "concurrency.threads" add-init-hook
|
[ init-threads ] "threads" add-init-hook
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2007 Doug Coleman.
|
! Copyright (C) 2007 Doug Coleman.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: arrays calendar combinators concurrency generic
|
USING: arrays calendar combinators concurrency.messaging
|
||||||
init kernel math namespaces sequences threads ;
|
threads generic init kernel math namespaces sequences ;
|
||||||
IN: alarms
|
IN: alarms
|
||||||
|
|
||||||
TUPLE: alarm time quot ;
|
TUPLE: alarm time quot ;
|
||||||
|
@ -36,7 +36,7 @@ SYMBOL: alarm-looper
|
||||||
[ alarm-time <=> 0 <= ] with subset ;
|
[ alarm-time <=> 0 <= ] with subset ;
|
||||||
|
|
||||||
: call-alarm ( alarm -- )
|
: call-alarm ( alarm -- )
|
||||||
alarm-quot spawn drop ;
|
alarm-quot "Alarm invocation" spawn drop ;
|
||||||
|
|
||||||
: do-alarms ( -- )
|
: do-alarms ( -- )
|
||||||
expired-alarms [ call-alarm ] each
|
expired-alarms [ call-alarm ] each
|
||||||
|
@ -49,7 +49,7 @@ SYMBOL: alarm-looper
|
||||||
: start-alarm-receiver ( -- )
|
: start-alarm-receiver ( -- )
|
||||||
[
|
[
|
||||||
alarm-receive-loop
|
alarm-receive-loop
|
||||||
] spawn alarm-receiver set-global ;
|
] "Alarm receiver" spawn alarm-receiver set-global ;
|
||||||
|
|
||||||
: alarm-loop ( -- )
|
: alarm-loop ( -- )
|
||||||
alarms get-global empty? [
|
alarms get-global empty? [
|
||||||
|
@ -59,7 +59,7 @@ SYMBOL: alarm-looper
|
||||||
: start-alarm-looper ( -- )
|
: start-alarm-looper ( -- )
|
||||||
[
|
[
|
||||||
alarm-loop
|
alarm-loop
|
||||||
] spawn alarm-looper set-global ;
|
] "Alarm looper" spawn alarm-looper set-global ;
|
||||||
|
|
||||||
: send-alarm ( str alarm -- )
|
: send-alarm ( str alarm -- )
|
||||||
over set-delegate
|
over set-delegate
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
USING: concurrency kernel tools.time math sequences ;
|
USING: threads concurrency.messaging kernel
|
||||||
|
tools.time math sequences ;
|
||||||
IN: benchmark.ring
|
IN: benchmark.ring
|
||||||
|
|
||||||
SYMBOL: done
|
SYMBOL: done
|
||||||
|
@ -7,7 +8,7 @@ SYMBOL: done
|
||||||
receive 2dup swap send done eq? [ tunnel ] unless ;
|
receive 2dup swap send done eq? [ tunnel ] unless ;
|
||||||
|
|
||||||
: create-ring ( processes -- target )
|
: create-ring ( processes -- target )
|
||||||
self swap [ [ tunnel ] spawn nip ] times ;
|
self swap [ [ tunnel ] "Tunnel" spawn nip ] times ;
|
||||||
|
|
||||||
: send-messages ( messages target -- )
|
: send-messages ( messages target -- )
|
||||||
dupd [ send ] curry each [ receive drop ] times ;
|
dupd [ send ] curry each [ receive drop ] times ;
|
||||||
|
@ -22,4 +23,3 @@ SYMBOL: done
|
||||||
1000 1000 ring-bench ;
|
1000 1000 ring-bench ;
|
||||||
|
|
||||||
MAIN: main-ring-bench
|
MAIN: main-ring-bench
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
USING: io.sockets io.server io kernel math threads debugger
|
USING: io.sockets io.server io kernel math threads
|
||||||
concurrency tools.time prettyprint ;
|
debugger tools.time prettyprint ;
|
||||||
IN: benchmark.sockets
|
IN: benchmark.sockets
|
||||||
|
|
||||||
: simple-server ( -- )
|
: simple-server ( -- )
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
! 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: calendar namespaces models concurrency.threads init ;
|
USING: calendar namespaces models threads init ;
|
||||||
IN: calendar.model
|
IN: calendar.model
|
||||||
|
|
||||||
SYMBOL: time
|
SYMBOL: time
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
!
|
!
|
||||||
! Examples of using channels
|
! Examples of using channels
|
||||||
USING: kernel concurrency channels math namespaces locals
|
USING: kernel threads channels math namespaces
|
||||||
sequences ;
|
locals sequences ;
|
||||||
IN: channels.examples
|
IN: channels.examples
|
||||||
|
|
||||||
: (counter) ( channel n -- )
|
: (counter) ( channel n -- )
|
||||||
|
@ -13,7 +13,7 @@ IN: channels.examples
|
||||||
2 (counter) ;
|
2 (counter) ;
|
||||||
|
|
||||||
: counter-test ( -- n1 n2 n3 )
|
: counter-test ( -- n1 n2 n3 )
|
||||||
<channel> [ counter ] spawn drop
|
<channel> dup [ counter ] curry "Counter" spawn drop
|
||||||
[ from ] keep [ from ] keep from ;
|
[ from ] keep [ from ] keep from ;
|
||||||
|
|
||||||
: filter ( send prime recv -- )
|
: filter ( send prime recv -- )
|
||||||
|
@ -34,11 +34,11 @@ IN: channels.examples
|
||||||
|
|
||||||
: sieve ( prime -- )
|
: sieve ( prime -- )
|
||||||
#! Send prime numbers to 'prime' channel
|
#! Send prime numbers to 'prime' channel
|
||||||
<channel> [ counter ] spawn drop
|
<channel> dup [ counter ] curry "Counter" spawn drop
|
||||||
(sieve) ;
|
(sieve) ;
|
||||||
|
|
||||||
: sieve-test ( -- seq )
|
: sieve-test ( -- seq )
|
||||||
<channel> [ sieve ] spawn drop
|
<channel> dup [ sieve ] curry "Sieve" spawn drop
|
||||||
V{ } clone swap
|
V{ } clone swap
|
||||||
[ from swap push ] 2keep
|
[ from swap push ] 2keep
|
||||||
[ from swap push ] 2keep
|
[ from swap push ] 2keep
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
!
|
!
|
||||||
! Remote Channels
|
! Remote Channels
|
||||||
USING: kernel init namespaces assocs arrays random
|
USING: kernel init namespaces assocs arrays random
|
||||||
sequences channels match concurrency concurrency.distributed ;
|
sequences channels match concurrency.messaging
|
||||||
|
concurrency.distributed ;
|
||||||
IN: channels.remote
|
IN: channels.remote
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
@ -40,8 +41,10 @@ SYMBOL: no-channel
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: start-channel-node ( -- )
|
: start-channel-node ( -- )
|
||||||
"remote-channels" get-process [
|
"remote-channels" get-process [
|
||||||
[ channel-process ] spawn "remote-channels" swap register-process
|
"remote-channels"
|
||||||
|
[ channel-process ] "Remote channels" spawn
|
||||||
|
register-process
|
||||||
] unless ;
|
] unless ;
|
||||||
|
|
||||||
TUPLE: remote-channel node id ;
|
TUPLE: remote-channel node id ;
|
||||||
|
|
|
@ -2,12 +2,15 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
!
|
!
|
||||||
! Wrap a sniffer in a channel
|
! Wrap a sniffer in a channel
|
||||||
USING: kernel channels channels.sniffer.backend concurrency io
|
USING: kernel channels channels.sniffer.backend
|
||||||
io.sniffer.backend io.sniffer.bsd io.unix.backend ;
|
threads io io.sniffer.backend io.sniffer.bsd
|
||||||
|
io.unix.backend ;
|
||||||
IN: channels.sniffer.bsd
|
IN: channels.sniffer.bsd
|
||||||
|
|
||||||
M: unix-io sniff-channel ( -- channel )
|
M: unix-io sniff-channel ( -- channel )
|
||||||
"/dev/bpf0" "en1" <sniffer-spec> <sniffer> <channel> [
|
"/dev/bpf0" "en1" <sniffer-spec> <sniffer> <channel> [
|
||||||
(sniff-channel)
|
[
|
||||||
] spawn drop nip ;
|
(sniff-channel)
|
||||||
|
] 3curry spawn drop
|
||||||
|
] keep ;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
! Copyright (C) 2006, 2007 Slava Pestov
|
! Copyright (C) 2006, 2007 Slava Pestov
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: alien io kernel namespaces core-foundation cocoa.messages
|
USING: alien io kernel namespaces core-foundation cocoa.messages
|
||||||
cocoa cocoa.classes cocoa.runtime sequences threads debugger
|
cocoa cocoa.classes cocoa.runtime sequences threads
|
||||||
init inspector kernel.private ;
|
debugger init inspector kernel.private ;
|
||||||
IN: cocoa.application
|
IN: cocoa.application
|
||||||
|
|
||||||
: <NSString> ( str -- alien ) <CFString> -> autorelease ;
|
: <NSString> ( str -- alien ) <CFString> -> autorelease ;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
USING: help.markup help.syntax concurrency ;
|
USING: help.markup help.syntax concurrency.messaging ;
|
||||||
IN: concurrency.distributed
|
IN: concurrency.distributed
|
||||||
|
|
||||||
HELP: <remote-process>
|
HELP: <remote-process>
|
||||||
|
@ -7,19 +7,9 @@ HELP: <remote-process>
|
||||||
{ "remote-process" "the constructed remote-process object" }
|
{ "remote-process" "the constructed remote-process object" }
|
||||||
}
|
}
|
||||||
{ $description "Constructs a proxy to a process running on another node. It can be used to send messages to the process it is acting as a proxy for." }
|
{ $description "Constructs a proxy to a process running on another node. It can be used to send messages to the process it is acting as a proxy for." }
|
||||||
{ $see-also <node> <process> spawn send } ;
|
{ $see-also spawn send } ;
|
||||||
|
|
||||||
|
|
||||||
HELP: <node>
|
|
||||||
{ $values { "hostname" "the hostname of the node as a string" }
|
|
||||||
{ "port" "the integer port number of the node" }
|
|
||||||
{ "node" "the constructed node object" }
|
|
||||||
}
|
|
||||||
{ $description "Processes run on nodes. Each node has a hostname and a port." }
|
|
||||||
{ $see-also localnode } ;
|
|
||||||
|
|
||||||
HELP: localnode
|
HELP: localnode
|
||||||
{ $values { "node" "a node object" }
|
{ $values { "node" "a node object" }
|
||||||
}
|
}
|
||||||
{ $description "Return the node the process is currently running on." }
|
{ $description "Return the node the process is currently running on." } ;
|
||||||
{ $see-also <node> } ;
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2005 Chris Double. All Rights Reserved.
|
! Copyright (C) 2005 Chris Double. All Rights Reserved.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: serialize sequences concurrency.messaging
|
USING: serialize sequences concurrency.messaging
|
||||||
concurrency.threads io io.server qualified arrays
|
threads io io.server qualified arrays
|
||||||
namespaces kernel ;
|
namespaces kernel ;
|
||||||
QUALIFIED: io.sockets
|
QUALIFIED: io.sockets
|
||||||
IN: concurrency.distributed
|
IN: concurrency.distributed
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
! 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: kernel concurrency.threads ;
|
USING: kernel threads ;
|
||||||
IN: concurrency.exchangers
|
IN: concurrency.exchangers
|
||||||
|
|
||||||
! Motivated by
|
! Motivated by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
! 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: dlists kernel concurrency.threads continuations math ;
|
USING: dlists kernel threads continuations math ;
|
||||||
IN: concurrency.locks
|
IN: concurrency.locks
|
||||||
|
|
||||||
! Simple critical sections
|
! Simple critical sections
|
||||||
|
|
|
@ -1,93 +1,80 @@
|
||||||
! Copyright (C) 2006 Chris Double.
|
! Copyright (C) 2006 Chris Double.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: help.syntax help.markup concurrency.private match ;
|
USING: help.syntax help.markup concurrency.messaging.private
|
||||||
IN: concurrency
|
threads ;
|
||||||
|
IN: concurrency.messaging
|
||||||
|
|
||||||
HELP: make-mailbox
|
HELP: <mailbox>
|
||||||
{ $values { "mailbox" "a mailbox object" }
|
{ $values { "mailbox" mailbox }
|
||||||
}
|
}
|
||||||
{ $description "A mailbox is an object that can be used for safe thread communication. Items can be put in the mailbox and retrieved in a FIFO order. If the mailbox is empty when a get operation is performed then the thread will block until another thread places something in the mailbox. If multiple threads are waiting on the same mailbox, only one of the waiting threads will be unblocked to process the get operation." }
|
{ $description "A mailbox is an object that can be used for safe thread communication. Items can be put in the mailbox and retrieved in a FIFO order. If the mailbox is empty when a get operation is performed then the thread will block until another thread places something in the mailbox. If multiple threads are waiting on the same mailbox, only one of the waiting threads will be unblocked to process the get operation." }
|
||||||
{ $see-also mailbox-empty? mailbox-put mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
{ $see-also mailbox-empty? mailbox-put mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
||||||
|
|
||||||
HELP: mailbox-empty?
|
HELP: mailbox-empty?
|
||||||
{ $values { "mailbox" "a mailbox object" }
|
{ $values { "mailbox" mailbox }
|
||||||
{ "bool" "a boolean value" }
|
{ "bool" "a boolean" }
|
||||||
}
|
}
|
||||||
{ $description "Return true if the mailbox is empty." }
|
{ $description "Return true if the mailbox is empty." }
|
||||||
{ $see-also make-mailbox mailbox-put mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
{ $see-also <mailbox> mailbox-put mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
||||||
|
|
||||||
HELP: mailbox-put
|
HELP: mailbox-put
|
||||||
{ $values { "obj" "an object" }
|
{ $values { "obj" "an object" }
|
||||||
{ "mailbox" "a mailbox object" }
|
{ "mailbox" mailbox }
|
||||||
}
|
}
|
||||||
{ $description "Put the object into the mailbox. Any threads that have a blocking get on the mailbox are resumed. Only one of those threads will successfully get the object, the rest will immediately block waiting for the next item in the mailbox." }
|
{ $description "Put the object into the mailbox. Any threads that have a blocking get on the mailbox are resumed. Only one of those threads will successfully get the object, the rest will immediately block waiting for the next item in the mailbox." }
|
||||||
{ $see-also make-mailbox mailbox-empty? mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
{ $see-also <mailbox> mailbox-empty? mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
||||||
|
|
||||||
HELP: (mailbox-block-unless-pred)
|
HELP: block-unless-pred
|
||||||
{ $values { "pred" "a quotation with stack effect " { $snippet "( X -- bool )" } }
|
{ $values { "pred" "a quotation with stack effect " { $snippet "( X -- bool )" } }
|
||||||
{ "mailbox" "a mailbox object" }
|
{ "mailbox" mailbox }
|
||||||
{ "timeout" "a timeout in milliseconds" }
|
{ "timeout" "a timeout in milliseconds" }
|
||||||
}
|
}
|
||||||
{ $description "Block the thread if there are no items in the mailbox that return true when the predicate is called with the item on the stack. The predicate must have stack effect " { $snippet "( X -- bool )" } "." }
|
{ $description "Block the thread if there are no items in the mailbox that return true when the predicate is called with the item on the stack." }
|
||||||
{ $see-also make-mailbox mailbox-empty? mailbox-put mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
{ $see-also <mailbox> mailbox-empty? mailbox-put mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
||||||
|
|
||||||
HELP: (mailbox-block-if-empty)
|
HELP: block-if-empty
|
||||||
{ $values { "mailbox" "a mailbox object" }
|
{ $values { "mailbox" mailbox }
|
||||||
{ "mailbox2" "same object as 'mailbox'" }
|
{ "mailbox2" "same object as 'mailbox'" }
|
||||||
{ "timeout" "a timeout in milliseconds" }
|
{ "timeout" "a timeout in milliseconds" }
|
||||||
}
|
}
|
||||||
{ $description "Block the thread if the mailbox is empty." }
|
{ $description "Block the thread if the mailbox is empty." }
|
||||||
{ $see-also make-mailbox mailbox-empty? mailbox-put mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
{ $see-also <mailbox> mailbox-empty? mailbox-put mailbox-get mailbox-get-all while-mailbox-empty mailbox-get? } ;
|
||||||
|
|
||||||
HELP: mailbox-get
|
HELP: mailbox-get
|
||||||
{ $values { "mailbox" "a mailbox object" }
|
{ $values { "mailbox" mailbox }
|
||||||
{ "obj" "an object" }
|
{ "obj" "an object" }
|
||||||
}
|
}
|
||||||
{ $description "Get the first item put into the mailbox. If it is empty the thread blocks until an item is put into it. The thread then resumes, leaving the item on the stack." }
|
{ $description "Get the first item put into the mailbox. If it is empty the thread blocks until an item is put into it. The thread then resumes, leaving the item on the stack." }
|
||||||
{ $see-also make-mailbox mailbox-empty? mailbox-put while-mailbox-empty mailbox-get-all mailbox-get? } ;
|
{ $see-also <mailbox> mailbox-empty? mailbox-put while-mailbox-empty mailbox-get-all mailbox-get? } ;
|
||||||
|
|
||||||
HELP: mailbox-get-all
|
HELP: mailbox-get-all
|
||||||
{ $values { "mailbox" "a mailbox object" }
|
{ $values { "mailbox" mailbox }
|
||||||
{ "array" "an array" }
|
{ "array" "an array" }
|
||||||
}
|
}
|
||||||
{ $description "Blocks the thread if the mailbox is empty, otherwise removes all objects in the mailbox and returns an array containing the objects." }
|
{ $description "Blocks the thread if the mailbox is empty, otherwise removes all objects in the mailbox and returns an array containing the objects." }
|
||||||
{ $see-also make-mailbox mailbox-empty? mailbox-put while-mailbox-empty mailbox-get-all mailbox-get? } ;
|
{ $see-also <mailbox> mailbox-empty? mailbox-put while-mailbox-empty mailbox-get-all mailbox-get? } ;
|
||||||
|
|
||||||
HELP: while-mailbox-empty
|
HELP: while-mailbox-empty
|
||||||
{ $values { "mailbox" "a mailbox object" }
|
{ $values { "mailbox" mailbox }
|
||||||
{ "quot" "a quotation with stack effect " { $snippet "( -- )" } }
|
{ "quot" "a quotation with stack effect " { $snippet "( -- )" } }
|
||||||
}
|
}
|
||||||
{ $description "Repeatedly call the quotation while there are no items in the mailbox. Quotation should have stack effect " { $snippet "( -- )" } "." }
|
{ $description "Repeatedly call the quotation while there are no items in the mailbox." }
|
||||||
{ $see-also make-mailbox mailbox-empty? mailbox-put mailbox-get mailbox-get-all mailbox-get? } ;
|
{ $see-also <mailbox> mailbox-empty? mailbox-put mailbox-get mailbox-get-all mailbox-get? } ;
|
||||||
|
|
||||||
HELP: mailbox-get?
|
HELP: mailbox-get?
|
||||||
{ $values { "pred" "a quotation with stack effect " { $snippet "( X -- bool )" } }
|
{ $values { "pred" "a quotation with stack effect " { $snippet "( X -- bool )" } }
|
||||||
{ "mailbox" "a mailbox object" }
|
{ "mailbox" mailbox }
|
||||||
{ "obj" "an object" }
|
{ "obj" "an object" }
|
||||||
}
|
}
|
||||||
{ $description "Get the first item in the mailbox which satisfies the predicate. 'pred' will be called repeatedly for each item in the mailbox. When 'pred' returns true that item will be returned. If nothing in the mailbox satisfies the predicate then the thread will block until something does. 'pred' must have stack effect " { $snippet "( X -- bool }" } "." }
|
{ $description "Get the first item in the mailbox which satisfies the predicate. 'pred' will be called repeatedly for each item in the mailbox. When 'pred' returns true that item will be returned. If nothing in the mailbox satisfies the predicate then the thread will block until something does." }
|
||||||
{ $see-also make-mailbox mailbox-empty? mailbox-put mailbox-get mailbox-get-all while-mailbox-empty } ;
|
{ $see-also <mailbox> mailbox-empty? mailbox-put mailbox-get mailbox-get-all while-mailbox-empty } ;
|
||||||
|
|
||||||
HELP: <process>
|
|
||||||
{ $values { "links" "an array of processes" }
|
|
||||||
{ "pid" "the process id" }
|
|
||||||
{ "mailbox" "a mailbox object" }
|
|
||||||
}
|
|
||||||
{ $description "Constructs a process object. A process is a lightweight thread with a mailbox that can be used to communicate with other processes. Each process has a unique process id." }
|
|
||||||
{ $see-also spawn send receive } ;
|
|
||||||
|
|
||||||
HELP: self
|
|
||||||
{ $values { "process" "a process object" }
|
|
||||||
}
|
|
||||||
{ $description "Returns the currently running process object." }
|
|
||||||
{ $see-also <process> send receive receive-if } ;
|
|
||||||
|
|
||||||
HELP: send
|
HELP: send
|
||||||
{ $values { "message" "an object" }
|
{ $values { "message" "an object" }
|
||||||
{ "process" "a process object" }
|
{ "process" "a process object" }
|
||||||
}
|
}
|
||||||
{ $description "Send the message to the process by placing it in the processes mailbox. This is an asynchronous operation and will return immediately. The receving process will act on the message the next time it retrieves that item from its mailbox (usually using the " { $link receive } " word. The message can be any Factor object. For destinations that are instances of remote-process the message must be a serializable Factor type." }
|
{ $description "Send the message to the process by placing it in the processes mailbox. This is an asynchronous operation and will return immediately. The receving process will act on the message the next time it retrieves that item from its mailbox (usually using the " { $link receive } " word. The message can be any Factor object. For destinations that are instances of remote-process the message must be a serializable Factor type." }
|
||||||
{ $see-also <process> receive receive-if } ;
|
{ $see-also receive receive-if } ;
|
||||||
|
|
||||||
HELP: receive
|
HELP: receive
|
||||||
{ $values { "message" "an object" }
|
{ $values { "message" "an object" }
|
||||||
|
@ -99,27 +86,16 @@ HELP: receive-if
|
||||||
{ $values { "pred" "a predicate with stack effect " { $snippet "( X -- bool )" } }
|
{ $values { "pred" "a predicate with stack effect " { $snippet "( X -- bool )" } }
|
||||||
{ "message" "an object" }
|
{ "message" "an object" }
|
||||||
}
|
}
|
||||||
{ $description "Return the first message from the current processes mailbox that satisfies the predicate. To satisfy the predicate, 'pred' is called with the item on the stack and the predicate should leave a boolean indicating whether it was satisfied or not. The predicate must have stack effect " { $snippet "( X -- bool )" } ". If nothing in the mailbox satisfies the predicate then the process will block until something does." }
|
{ $description "Return the first message from the current processes mailbox that satisfies the predicate. To satisfy the predicate, 'pred' is called with the item on the stack and the predicate should leave a boolean indicating whether it was satisfied or not. If nothing in the mailbox satisfies the predicate then the process will block until something does." }
|
||||||
{ $see-also send receive } ;
|
{ $see-also send receive } ;
|
||||||
|
|
||||||
HELP: spawn
|
HELP: spawn-linked
|
||||||
{ $values { "quot" "a predicate with stack effect " { $snippet "( -- )" } }
|
|
||||||
{ "process" "a process object" }
|
|
||||||
}
|
|
||||||
{ $description "Start a process which runs the given quotation." }
|
|
||||||
{ $see-also send receive receive-if self spawn-link } ;
|
|
||||||
|
|
||||||
HELP: spawn-link
|
|
||||||
{ $values { "quot" "a predicate with stack effect " { $snippet "( -- )" } }
|
{ $values { "quot" "a predicate with stack effect " { $snippet "( -- )" } }
|
||||||
{ "process" "a process object" }
|
{ "process" "a process object" }
|
||||||
}
|
}
|
||||||
{ $description "Start a process which runs the given quotation. If that quotation throws an error which is not caught then the error will get propagated to the process that spawned it. This can be used to set up 'supervisor' processes that restart child processes that crash due to uncaught errors.\n" }
|
{ $description "Start a process which runs the given quotation. If that quotation throws an error which is not caught then the error will get propagated to the process that spawned it. This can be used to set up 'supervisor' processes that restart child processes that crash due to uncaught errors.\n" }
|
||||||
{ $see-also spawn } ;
|
{ $see-also spawn } ;
|
||||||
|
|
||||||
ARTICLE: { "concurrency" "loading" } "Loading"
|
|
||||||
"The Factor module system can be used to load the Concurrency library:"
|
|
||||||
{ $code "USING: concurrency ;" } ;
|
|
||||||
|
|
||||||
ARTICLE: { "concurrency" "processes" } "Processes"
|
ARTICLE: { "concurrency" "processes" } "Processes"
|
||||||
"A process is basically a thread with a message queue. Other processes can place items on this queue by sending the process a message. A process can check its queue for messages, blocking if none are pending, and process them as they are queued.\n\nFactor processes are very lightweight. Each process can take as little as 900 bytes of memory. This library has been tested running hundreds of thousands of simple processes.\n\nThe messages that are sent from process to process are any Factor value. Factor tuples are ideal for this sort of thing as you can send a tuple to a process and the predicate dispatch mechanism can be used to perform actions depending on what the type of the tuple is.\n\nProcesses are usually created using " { $link spawn } ". This word takes a quotation on the stack and starts a process that will execute that quotation asynchronously. When the quotation completes the process will die. 'spawn' leaves on the stack the process object that was started. This object can be used to send messages to the process using " { $link send } ".\n\n'send' will return immediately after placing the message in the target processes message queue.\n\nA process can get a message from its queue using " { $link receive } ". This will get the most recent message and leave it on the stack. If there are no messages in the queue the process will 'block' until a message is available. When a process is blocked it takes no CPU time at all."
|
"A process is basically a thread with a message queue. Other processes can place items on this queue by sending the process a message. A process can check its queue for messages, blocking if none are pending, and process them as they are queued.\n\nFactor processes are very lightweight. Each process can take as little as 900 bytes of memory. This library has been tested running hundreds of thousands of simple processes.\n\nThe messages that are sent from process to process are any Factor value. Factor tuples are ideal for this sort of thing as you can send a tuple to a process and the predicate dispatch mechanism can be used to perform actions depending on what the type of the tuple is.\n\nProcesses are usually created using " { $link spawn } ". This word takes a quotation on the stack and starts a process that will execute that quotation asynchronously. When the quotation completes the process will die. 'spawn' leaves on the stack the process object that was started. This object can be used to send messages to the process using " { $link send } ".\n\n'send' will return immediately after placing the message in the target processes message queue.\n\nA process can get a message from its queue using " { $link receive } ". This will get the most recent message and leave it on the stack. If there are no messages in the queue the process will 'block' until a message is available. When a process is blocked it takes no CPU time at all."
|
||||||
{ $code "[ receive print ] spawn\n\"Hello Process!\" swap send" }
|
{ $code "[ receive print ] spawn\n\"Hello Process!\" swap send" }
|
||||||
|
@ -130,14 +106,9 @@ ARTICLE: { "concurrency" "self" } "Self"
|
||||||
"A process can get access to its own process object using " { $link self } " so it can pass it to other processes. This allows the other processes to send messages back. A simple example of using this gets the current process' 'self' and spawns a process which sends a message to it. We then receive the message from the original process:"
|
"A process can get access to its own process object using " { $link self } " so it can pass it to other processes. This allows the other processes to send messages back. A simple example of using this gets the current process' 'self' and spawns a process which sends a message to it. We then receive the message from the original process:"
|
||||||
{ $code "self [ \"Hello!\" swap send ] spawn 2drop receive .\n => \"Hello!\"" } ;
|
{ $code "self [ \"Hello!\" swap send ] spawn 2drop receive .\n => \"Hello!\"" } ;
|
||||||
|
|
||||||
ARTICLE: { "concurrency" "servers" } "Servers"
|
|
||||||
"A common idiom is to create 'server' processes that act on messages that are sent to it. These follow a basic pattern of blocking until a message is received, processing that message then looping back to blocking for a message.\n\nThe following example shows a very simple server that expects an array as its message. The first item of the array should be the senders process object. If the second item is 'ping' then the server sends 'pong' back to the caller. If the second item is anything else then the server exits:"
|
|
||||||
{ $code ": pong-server ( -- )\n receive {\n { { ?from \"ping\" } [ \"pong\" ?from send pong-server ] }\n { { ?from _ } [ \"server shutdown\" ?from send ] }\n } match-cond ;\n\n[ pong-server ] spawn" }
|
|
||||||
"Handling the deconstructing of messages and dispatching based on the message can be a bit of a chore. Especially in servers that take a number of different messages. The approach taken above is to use the 'match' library which allows easy deconstructing of messages using " { $link match-cond } "." ;
|
|
||||||
|
|
||||||
ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous Sends"
|
ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous Sends"
|
||||||
{ $link send } " sends a message asynchronously, and the sending process continues immediately. The 'pong server' example shown previously all sent messages to the server and waited for a reply back from the server. This pattern of synchronous sending is made easier with " { $link send-synchronous } ".\n\nThis word will send a message to the given process and immediately block until a reply is received for this particular message send. It leaves the reply on the stack. Note that it doesn't wait for just any reply, it waits for a reply specifically to this send.\n\nTo do this it wraps the requested message inside a tagged message format using " { $link tag-message } ":"
|
{ $link send } " sends a message asynchronously, and the sending process continues immediately. The 'pong server' example shown previously all sent messages to the server and waited for a reply back from the server. This pattern of synchronous sending is made easier with " { $link send-synchronous } ".\n\nThis word will send a message to the given process and immediately block until a reply is received for this particular message send. It leaves the reply on the stack. Note that it doesn't wait for just any reply, it waits for a reply specifically to this send.\n\nTo do this it wraps the requested message inside a tagged message format using " { $link <synchronous> } ":"
|
||||||
{ $code "\"My Message\" tag-message .\n => { ...from... ...tag... \"My Message\" }" }
|
{ $code "\"My Message\" <synchronous> .\n => T{ synchronous f \"My Message\" ...from... ...tag... }" }
|
||||||
"The message is wrapped in array where the first item is the sending process object, the second is a unique tag, and the third is the original message. Server processes can use the 'from' to reply to the process that originally sent the message. The tag is used in the receiving server to include the value in the reply. After the send-synchronous call the current process will block waiting for a reply that has the exact same tag. In this way you can be sure that the reply you got was for the specific message sent. Here is the pong-server recoded to use 'send-synchronous':"
|
"The message is wrapped in array where the first item is the sending process object, the second is a unique tag, and the third is the original message. Server processes can use the 'from' to reply to the process that originally sent the message. The tag is used in the receiving server to include the value in the reply. After the send-synchronous call the current process will block waiting for a reply that has the exact same tag. In this way you can be sure that the reply you got was for the specific message sent. Here is the pong-server recoded to use 'send-synchronous':"
|
||||||
{ $code ": pong-server ( -- )\n receive {\n { { ?from ?tag \"ping\" } [ ?tag \"pong\" 2array ?from send pong-server ] }\n { { ?from _ } [ ?tag \"server shutdown\" 2array ?from send ] }\n } match-cond ;\n\n[ pong-server ] spawn \"ping\" swap send-synchronous .\n => \"pong\"" }
|
{ $code ": pong-server ( -- )\n receive {\n { { ?from ?tag \"ping\" } [ ?tag \"pong\" 2array ?from send pong-server ] }\n { { ?from _ } [ ?tag \"server shutdown\" 2array ?from send ] }\n } match-cond ;\n\n[ pong-server ] spawn \"ping\" swap send-synchronous .\n => \"pong\"" }
|
||||||
"Notice that the code to send the reply back to the original caller wraps the reply in an array where the first item is the tag originally sent. 'send-synchronous' only returns if it receives a reply containing that specific tag." ;
|
"Notice that the code to send the reply back to the original caller wraps the reply in an array where the first item is the tag originally sent. 'send-synchronous' only returns if it receives a reply containing that specific tag." ;
|
||||||
|
@ -145,27 +116,15 @@ ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous Sends"
|
||||||
ARTICLE: { "concurrency" "exceptions" } "Exceptions"
|
ARTICLE: { "concurrency" "exceptions" } "Exceptions"
|
||||||
"A process can handle exceptions using the standard Factor exception handling mechanism. If an exception is uncaught the process will terminate. For example:"
|
"A process can handle exceptions using the standard Factor exception handling mechanism. If an exception is uncaught the process will terminate. For example:"
|
||||||
{ $code "[ 1 0 / \"This will not print\" print ] spawn" }
|
{ $code "[ 1 0 / \"This will not print\" print ] spawn" }
|
||||||
"Processes can be linked so that a parent process can receive the exception that caused the child process to terminate. In this way 'supervisor' processes can be created that are notified when child processes terminate and possibly restart them.\n\nThe easiest way to form this link is using " { $link spawn-link } ". This will create a unidirectional link, such that if an uncaught exception causes the child to terminate, the parent process can catch it:"
|
"Processes can be linked so that a parent process can receive the exception that caused the child process to terminate. In this way 'supervisor' processes can be created that are notified when child processes terminate and possibly restart them.\n\nThe easiest way to form this link is using " { $link spawn-linked } ". This will create a unidirectional link, such that if an uncaught exception causes the child to terminate, the parent process can catch it:"
|
||||||
{ $code "[\n [ 1 0 / \"This will not print\" print ] spawn-link drop\n receive\n] [ \"Exception caught.\" print ] recover" }
|
{ $code "[\n [ 1 0 / \"This will not print\" print ] spawn-link drop\n receive\n] [ \"Exception caught.\" print ] recover" }
|
||||||
"Exceptions are only raised in the parent when the parent does a " { $link receive } " or " { $link receive-if } ". This is because the exception is sent from the child to the parent as a message." ;
|
"Exceptions are only raised in the parent when the parent does a " { $link receive } " or " { $link receive-if } ". This is because the exception is sent from the child to the parent as a message." ;
|
||||||
|
|
||||||
ARTICLE: { "concurrency" "futures" } "Futures"
|
|
||||||
"A future is a placeholder for the result of a computation that is being calculated in a process. When the process has completed the computation the future can be queried to find out the result. If the computation has not completed when the future is queried them the process will block until the result is completed. A future is created using " { $link future } ".\n\nThe quotation will be run in a spawned process, and a future object is immediately returned. This future object can be resolved using " { $link ?future } ".\n\nFutures are useful for starting calculations that take a long time to run but aren't needed until later in the process. When the process needs the value it can use '?future' to get the result or block until the result is available. For example:"
|
|
||||||
{ $code "[ 30 fib ] future\n...do stuff...\n?future" } ;
|
|
||||||
|
|
||||||
ARTICLE: { "concurrency" "promises" } "Promises"
|
|
||||||
"A promise is similar to a future but it is not produced by calculating something in the background. It represents a promise to provide a value sometime later. A process can request the value of a promise and will block if the promise is not fulfilled. Later, another process can fulfill the promise, providing a value. All threads waiting on the promise will then resume with that value on the stack. Use " { $link <promise> } " to create a promise, " { $link fulfill } " to set it to a value, and " { $link ?promise } " to retrieve the value, or block until the promise is fulfilled:"
|
|
||||||
{ $code "<promise>\n[ ?promise \"Promise fulfilled: \" write print ] spawn drop\n[ ?promise \"Promise fulfilled: \" write print ] spawn drop\n[ ?promise \"Promise fulfilled: \" write print ] spawn drop\n\"hello\" swap fulfill\n => Promise fulfilled: hello\n Promise fulfilled: hello\n Promise fulfilled: hello" } ;
|
|
||||||
|
|
||||||
ARTICLE: { "concurrency" "concurrency" } "Concurrency"
|
ARTICLE: { "concurrency" "concurrency" } "Concurrency"
|
||||||
"The concurrency library is based upon the style of concurrency used in systems like Erlang and Termite. It is built on top of the standard Factor lightweight thread system.\nA concurrency oriented program is one in which multiple processes run simultaneously in a single Factor image or across multiple running Factor instances. The processes can communicate with each other by asynchronous message sends. Although processes can share data via Factor's mutable data structures it is not recommended as the use of shared state concurrency is often a cause of problems."
|
"The concurrency library is based upon the style of concurrency used in systems like Erlang and Termite. It is built on top of the standard Factor lightweight thread system.\nA concurrency oriented program is one in which multiple processes run simultaneously in a single Factor image or across multiple running Factor instances. The processes can communicate with each other by asynchronous message sends. Although processes can share data via Factor's mutable data structures it is not recommended as the use of shared state concurrency is often a cause of problems."
|
||||||
{ $subsection { "concurrency" "loading" } }
|
|
||||||
{ $subsection { "concurrency" "processes" } }
|
{ $subsection { "concurrency" "processes" } }
|
||||||
{ $subsection { "concurrency" "self" } }
|
{ $subsection { "concurrency" "self" } }
|
||||||
{ $subsection { "concurrency" "servers" } }
|
|
||||||
{ $subsection { "concurrency" "synchronous-sends" } }
|
{ $subsection { "concurrency" "synchronous-sends" } }
|
||||||
{ $subsection { "concurrency" "exceptions" } }
|
{ $subsection { "concurrency" "exceptions" } } ;
|
||||||
{ $subsection { "concurrency" "futures" } }
|
|
||||||
{ $subsection { "concurrency" "promises" } } ;
|
|
||||||
|
|
||||||
ABOUT: { "concurrency" "concurrency" }
|
ABOUT: { "concurrency" "concurrency" }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2005 Chris Double. All Rights Reserved.
|
! Copyright (C) 2005 Chris Double. All Rights Reserved.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
!
|
!
|
||||||
USING: kernel concurrency threads vectors arrays sequences
|
USING: kernel threads vectors arrays sequences
|
||||||
namespaces tools.test continuations dlists strings math words
|
namespaces tools.test continuations dlists strings math words
|
||||||
match quotations concurrency.private ;
|
match quotations concurrency.private ;
|
||||||
IN: temporary
|
IN: temporary
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
! Concurrency library for Factor based on Erlang/Termite style
|
! Concurrency library for Factor based on Erlang/Termite style
|
||||||
! concurrency.
|
! concurrency.
|
||||||
IN: concurrency.messaging
|
IN: concurrency.messaging
|
||||||
USING: dlists concurrency.threads sequences continuations
|
USING: dlists threads sequences continuations
|
||||||
namespaces random math quotations words kernel arrays assocs
|
namespaces random math quotations words kernel arrays assocs
|
||||||
init system ;
|
init system ;
|
||||||
|
|
||||||
TUPLE: mailbox threads data ;
|
TUPLE: mailbox threads data ;
|
||||||
|
|
||||||
: <mailbox> ( -- mailbox )
|
: <mailbox> ( -- mailbox )
|
||||||
<dlist> <dlist> mailbox construct-boa ;
|
<dlist> <dlist> \ mailbox construct-boa ;
|
||||||
|
|
||||||
: mailbox-empty? ( mailbox -- bool )
|
: mailbox-empty? ( mailbox -- bool )
|
||||||
mailbox-data dlist-empty? ;
|
mailbox-data dlist-empty? ;
|
||||||
|
@ -52,16 +52,16 @@ PRIVATE>
|
||||||
block-if-empty mailbox-data pop-front ;
|
block-if-empty mailbox-data pop-front ;
|
||||||
|
|
||||||
: mailbox-get ( mailbox -- obj )
|
: mailbox-get ( mailbox -- obj )
|
||||||
f mailbox-timeout-get ;
|
f mailbox-get-timeout ;
|
||||||
|
|
||||||
: mailbox-get-all-timeout ( mailbox timeout -- array )
|
: mailbox-get-all-timeout ( mailbox timeout -- array )
|
||||||
(mailbox-block-if-empty)
|
block-if-empty
|
||||||
[ dup mailbox-empty? ]
|
[ dup mailbox-empty? ]
|
||||||
[ dup mailbox-data pop-back ]
|
[ dup mailbox-data pop-back ]
|
||||||
[ ] unfold nip ;
|
[ ] unfold nip ;
|
||||||
|
|
||||||
: mailbox-get-all ( mailbox -- array )
|
: mailbox-get-all ( mailbox -- array )
|
||||||
f mailbox-timeout-get-all ;
|
f mailbox-get-all-timeout ;
|
||||||
|
|
||||||
: while-mailbox-empty ( mailbox quot -- )
|
: while-mailbox-empty ( mailbox quot -- )
|
||||||
over mailbox-empty? [
|
over mailbox-empty? [
|
||||||
|
@ -71,7 +71,7 @@ PRIVATE>
|
||||||
] if ; inline
|
] if ; inline
|
||||||
|
|
||||||
: mailbox-timeout-get? ( pred mailbox timeout -- obj )
|
: mailbox-timeout-get? ( pred mailbox timeout -- obj )
|
||||||
[ (mailbox-block-unless-pred) ] 3keep drop
|
[ block-unless-pred ] 3keep drop
|
||||||
mailbox-data delete-node-if ; inline
|
mailbox-data delete-node-if ; inline
|
||||||
|
|
||||||
: mailbox-get? ( pred mailbox -- obj )
|
: mailbox-get? ( pred mailbox -- obj )
|
||||||
|
@ -83,12 +83,17 @@ TUPLE: linked error thread ;
|
||||||
|
|
||||||
GENERIC: send ( message thread -- )
|
GENERIC: send ( message thread -- )
|
||||||
|
|
||||||
|
: mailbox-of ( thread -- mailbox )
|
||||||
|
dup thread-mailbox [ ] [
|
||||||
|
<mailbox> dup rot set-thread-mailbox
|
||||||
|
] ?if ;
|
||||||
|
|
||||||
M: thread send ( message thread -- )
|
M: thread send ( message thread -- )
|
||||||
thread-mailbox mailbox-put ;
|
mailbox-of mailbox-put ;
|
||||||
|
|
||||||
: ?linked dup linked? [ rethrow ] when ;
|
: ?linked dup linked? [ rethrow ] when ;
|
||||||
|
|
||||||
: mailbox self thread-mailbox ;
|
: mailbox self mailbox-of ;
|
||||||
|
|
||||||
: receive ( -- message )
|
: receive ( -- message )
|
||||||
mailbox mailbox-get ?linked ;
|
mailbox mailbox-get ?linked ;
|
||||||
|
@ -118,4 +123,4 @@ TUPLE: reply data tag ;
|
||||||
receive-if reply-data ;
|
receive-if reply-data ;
|
||||||
|
|
||||||
: reply-synchronous ( message synchronous -- )
|
: reply-synchronous ( message synchronous -- )
|
||||||
[ <reply> ] keep synchronous-sender reply ;
|
[ <reply> ] keep synchronous-sender send ;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
USING: kernel math math-contrib sequences namespaces errors
|
USING: kernel math math-contrib sequences namespaces errors
|
||||||
hashtables words arrays parser compiler syntax io threads ;
|
hashtables words arrays parser compiler syntax io ;
|
||||||
IN: crypto
|
IN: crypto
|
||||||
: make-bits ( quot numbits -- n | quot: -- 0/1 )
|
: make-bits ( quot numbits -- n | quot: -- 0/1 )
|
||||||
0 -rot [ drop dup call rot 1 shift bitor swap ] each drop ;
|
0 -rot [ drop dup call rot 1 shift bitor swap ] each drop ;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: io io.backend io.timeouts system kernel namespaces
|
USING: io io.backend io.timeouts system kernel namespaces
|
||||||
strings hashtables sequences assocs combinators vocabs.loader
|
strings hashtables sequences assocs combinators vocabs.loader
|
||||||
init concurrency.threads continuations math ;
|
init threads continuations math ;
|
||||||
IN: io.launcher
|
IN: io.launcher
|
||||||
|
|
||||||
! Non-blocking process exit notification facility
|
! Non-blocking process exit notification facility
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! 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 namespaces sequences
|
USING: io.backend kernel continuations namespaces sequences
|
||||||
assocs hashtables sorting arrays concurrency.threads ;
|
assocs hashtables sorting arrays threads ;
|
||||||
IN: io.monitors
|
IN: io.monitors
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: io io.sockets io.files logging continuations kernel
|
USING: io io.sockets io.files logging continuations kernel
|
||||||
math math.parser namespaces parser sequences strings
|
math math.parser namespaces parser sequences strings
|
||||||
prettyprint debugger quotations calendar qualified ;
|
prettyprint debugger quotations calendar
|
||||||
QUALIFIED: concurrency
|
threads concurrency.futures ;
|
||||||
|
|
||||||
IN: io.server
|
IN: io.server
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ LOG: accepted-connection NOTICE
|
||||||
: accept-loop ( server quot -- )
|
: accept-loop ( server quot -- )
|
||||||
[
|
[
|
||||||
>r accept r> [ with-client ] 2curry
|
>r accept r> [ with-client ] 2curry
|
||||||
concurrency:spawn drop
|
"Client" spawn drop
|
||||||
] 2keep accept-loop ; inline
|
] 2keep accept-loop ; inline
|
||||||
|
|
||||||
: server-loop ( server quot -- )
|
: server-loop ( server quot -- )
|
||||||
|
@ -42,7 +42,7 @@ SYMBOL: servers
|
||||||
: with-server ( seq service quot -- )
|
: with-server ( seq service quot -- )
|
||||||
[
|
[
|
||||||
V{ } clone servers set
|
V{ } clone servers set
|
||||||
[ spawn-server ] curry concurrency:parallel-each
|
[ spawn-server ] curry parallel-each
|
||||||
] curry with-logging ; inline
|
] curry with-logging ; inline
|
||||||
|
|
||||||
: stop-server ( -- )
|
: stop-server ( -- )
|
||||||
|
@ -65,5 +65,5 @@ SYMBOL: servers
|
||||||
|
|
||||||
: with-datagrams ( seq service quot -- )
|
: with-datagrams ( seq service quot -- )
|
||||||
[
|
[
|
||||||
[ swap spawn-datagrams ] curry concurrency:parallel-each
|
[ swap spawn-datagrams ] curry parallel-each
|
||||||
] curry with-logging ; inline
|
] curry with-logging ; inline
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
USING: help.markup help.syntax io io.backend concurrency.threads
|
USING: help.markup help.syntax io io.backend threads
|
||||||
strings byte-arrays continuations ;
|
strings byte-arrays continuations ;
|
||||||
IN: io.sockets
|
IN: io.sockets
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2008 Slava Pestov, Doug Coleman
|
! Copyright (C) 2008 Slava Pestov, Doug Coleman
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel math system dlists namespaces assocs init
|
USING: kernel math system dlists namespaces assocs init
|
||||||
concurrency.threads io.streams.duplex ;
|
threads io.streams.duplex ;
|
||||||
IN: io.timeouts
|
IN: io.timeouts
|
||||||
|
|
||||||
TUPLE: lapse entry timeout cutoff ;
|
TUPLE: lapse entry timeout cutoff ;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
! Copyright (C) 2004, 2008 Slava Pestov.
|
! Copyright (C) 2004, 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: alien generic assocs kernel kernel.private math
|
USING: alien generic assocs kernel kernel.private math
|
||||||
io.nonblocking sequences strings structs sbufs threads unix
|
io.nonblocking sequences strings structs sbufs
|
||||||
vectors io.buffers io.backend io.streams.duplex math.parser
|
threads unix vectors io.buffers io.backend
|
||||||
continuations system libc qualified namespaces io.timeouts ;
|
io.streams.duplex math.parser continuations system libc
|
||||||
|
qualified namespaces io.timeouts ;
|
||||||
QUALIFIED: io
|
QUALIFIED: io
|
||||||
IN: io.unix.backend
|
IN: io.unix.backend
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
IN: io.unix.bsd
|
IN: io.unix.bsd
|
||||||
USING: io.backend io.unix.backend io.unix.kqueue io.unix.select
|
USING: io.backend io.unix.backend io.unix.kqueue io.unix.select
|
||||||
io.launcher io.unix.launcher namespaces kernel assocs threads
|
io.launcher io.unix.launcher namespaces kernel assocs
|
||||||
continuations ;
|
threads continuations ;
|
||||||
|
|
||||||
! On Mac OS X, we use select() for the top-level
|
! On Mac OS X, we use select() for the top-level
|
||||||
! multiplexer, and we hang a kqueue off of it for process exit
|
! multiplexer, and we hang a kqueue off of it for process exit
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: alien.c-types kernel io.nonblocking io.unix.backend
|
USING: alien.c-types kernel io.nonblocking io.unix.backend
|
||||||
sequences assocs unix unix.kqueue unix.process math namespaces
|
sequences assocs unix unix.kqueue unix.process math namespaces
|
||||||
combinators threads vectors io.launcher io.unix.launcher ;
|
combinators threads vectors io.launcher
|
||||||
|
io.unix.launcher ;
|
||||||
IN: io.unix.kqueue
|
IN: io.unix.kqueue
|
||||||
|
|
||||||
TUPLE: kqueue-mx events ;
|
TUPLE: kqueue-mx events ;
|
||||||
|
|
|
@ -120,8 +120,6 @@ M: unix-io process-stream*
|
||||||
] if
|
] if
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
: wait-loop ( -- )
|
|
||||||
wait-for-processes [ 250 sleep ] when wait-loop ;
|
|
||||||
|
|
||||||
: start-wait-thread ( -- )
|
: start-wait-thread ( -- )
|
||||||
[ wait-loop ] "Process reaper" spawn drop ;
|
[ wait-for-processes [ 250 sleep ] when t ]
|
||||||
|
"Process reaper" spawn-server drop ;
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
USING: kernel io.backend io.monitors io.monitors.private
|
USING: kernel io.backend io.monitors io.monitors.private
|
||||||
io.files io.buffers io.nonblocking io.timeouts io.unix.backend
|
io.files io.buffers io.nonblocking io.timeouts io.unix.backend
|
||||||
io.unix.select io.unix.launcher unix.linux.inotify assocs
|
io.unix.select io.unix.launcher unix.linux.inotify assocs
|
||||||
namespaces threads continuations init math alien.c-types alien
|
namespaces threads continuations init math
|
||||||
vocabs.loader ;
|
alien.c-types alien vocabs.loader ;
|
||||||
IN: io.unix.linux
|
IN: io.unix.linux
|
||||||
|
|
||||||
TUPLE: linux-io ;
|
TUPLE: linux-io ;
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
! We need to fiddle with the exact search order here, since
|
! We need to fiddle with the exact search order here, since
|
||||||
! unix::accept shadows streams::accept.
|
! unix::accept shadows streams::accept.
|
||||||
IN: io.unix.sockets
|
IN: io.unix.sockets
|
||||||
USING: alien alien.c-types generic io
|
USING: alien alien.c-types generic io kernel math namespaces
|
||||||
kernel math namespaces io.nonblocking parser threads unix
|
io.nonblocking parser threads unix sequences
|
||||||
sequences byte-arrays io.sockets io.binary io.unix.backend
|
byte-arrays io.sockets io.binary io.unix.backend
|
||||||
io.streams.duplex io.sockets.impl math.parser continuations
|
io.streams.duplex io.sockets.impl math.parser continuations libc
|
||||||
libc combinators ;
|
combinators ;
|
||||||
|
|
||||||
: pending-init-error ( port -- )
|
: pending-init-error ( port -- )
|
||||||
#! We close it here to avoid a resource leak; callers of
|
#! We close it here to avoid a resource leak; callers of
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: io.files io.sockets io kernel threads namespaces
|
USING: io.files io.sockets io kernel threads
|
||||||
tools.test continuations strings byte-arrays sequences
|
namespaces tools.test continuations strings byte-arrays
|
||||||
prettyprint system ;
|
sequences prettyprint system ;
|
||||||
IN: temporary
|
IN: temporary
|
||||||
|
|
||||||
! Unix domain stream sockets
|
! Unix domain stream sockets
|
||||||
|
|
|
@ -4,7 +4,7 @@ USING: alien alien.c-types arrays continuations destructors io
|
||||||
io.windows io.windows.nt.pipes libc io.nonblocking
|
io.windows io.windows.nt.pipes libc io.nonblocking
|
||||||
io.streams.duplex windows.types math windows.kernel32 windows
|
io.streams.duplex windows.types math windows.kernel32 windows
|
||||||
namespaces io.launcher kernel sequences windows.errors assocs
|
namespaces io.launcher kernel sequences windows.errors assocs
|
||||||
splitting system concurrency.threads init strings combinators
|
splitting system threads init strings combinators
|
||||||
io.backend ;
|
io.backend ;
|
||||||
IN: io.windows.launcher
|
IN: io.windows.launcher
|
||||||
|
|
||||||
|
@ -147,10 +147,9 @@ M: windows-io kill-process* ( handle -- )
|
||||||
: wait-loop ( -- )
|
: wait-loop ( -- )
|
||||||
processes get dup assoc-empty?
|
processes get dup assoc-empty?
|
||||||
[ drop t ] [ wait-for-processes ] if
|
[ drop t ] [ wait-for-processes ] if
|
||||||
[ 250 sleep ] when
|
[ 250 sleep ] when ;
|
||||||
wait-loop ;
|
|
||||||
|
|
||||||
: start-wait-thread ( -- )
|
: start-wait-thread ( -- )
|
||||||
[ wait-loop ] "Process wait" spawn drop ;
|
[ wait-loop t ] "Process wait" spawn-server drop ;
|
||||||
|
|
||||||
[ start-wait-thread ] "io.windows.launcher" add-init-hook
|
[ start-wait-thread ] "io.windows.launcher" add-init-hook
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
USING: alien alien.c-types arrays assocs combinators
|
USING: alien alien.c-types arrays assocs combinators
|
||||||
continuations destructors io io.backend io.nonblocking
|
continuations destructors io io.backend io.nonblocking
|
||||||
io.windows libc kernel math namespaces sequences
|
io.windows libc kernel math namespaces sequences
|
||||||
concurrency.threads tuples.lib windows windows.errors
|
threads tuples.lib windows windows.errors
|
||||||
windows.kernel32 strings splitting io.files qualified ascii
|
windows.kernel32 strings splitting io.files qualified ascii
|
||||||
combinators.lib ;
|
combinators.lib ;
|
||||||
QUALIFIED: windows.winsock
|
QUALIFIED: windows.winsock
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: continuations destructors io.buffers io.files io.backend
|
USING: continuations destructors io.buffers io.files io.backend
|
||||||
io.timeouts io.nonblocking io.windows io.windows.nt.backend
|
io.timeouts io.nonblocking io.windows io.windows.nt.backend
|
||||||
kernel libc math concurrency.threads windows windows.kernel32
|
kernel libc math threads windows windows.kernel32
|
||||||
alien.c-types alien.arrays sequences combinators combinators.lib
|
alien.c-types alien.arrays sequences combinators combinators.lib
|
||||||
sequences.lib ascii splitting alien strings assocs ;
|
sequences.lib ascii splitting alien strings assocs ;
|
||||||
IN: io.windows.nt.files
|
IN: io.windows.nt.files
|
||||||
|
|
|
@ -2,7 +2,7 @@ USING: alien alien.accessors alien.c-types byte-arrays
|
||||||
continuations destructors io.nonblocking io.timeouts io.sockets
|
continuations destructors io.nonblocking io.timeouts io.sockets
|
||||||
io.sockets.impl io namespaces io.streams.duplex io.windows
|
io.sockets.impl io namespaces io.streams.duplex io.windows
|
||||||
io.windows.nt.backend windows.winsock kernel libc math sequences
|
io.windows.nt.backend windows.winsock kernel libc math sequences
|
||||||
concurrency.threads tuples.lib ;
|
threads tuples.lib ;
|
||||||
IN: io.windows.nt.sockets
|
IN: io.windows.nt.sockets
|
||||||
|
|
||||||
: malloc-int ( object -- object )
|
: malloc-int ( object -- object )
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
! Copyright (C) 2003, 2008 Slava Pestov.
|
! Copyright (C) 2003, 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: logging.server sequences namespaces concurrency
|
USING: logging.server sequences namespaces concurrency.messaging
|
||||||
words kernel arrays shuffle tools.annotations
|
words kernel arrays shuffle tools.annotations
|
||||||
prettyprint.config prettyprint debugger io.streams.string
|
prettyprint.config prettyprint debugger io.streams.string
|
||||||
splitting continuations effects arrays.lib parser strings
|
splitting continuations effects arrays.lib parser strings
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: namespaces kernel io calendar sequences io.files
|
USING: namespaces kernel io calendar sequences io.files
|
||||||
io.sockets continuations prettyprint assocs math.parser
|
io.sockets continuations prettyprint assocs math.parser
|
||||||
words debugger math combinators concurrency arrays init
|
words debugger math combinators concurrency.messaging
|
||||||
math.ranges strings ;
|
threads arrays init math.ranges strings ;
|
||||||
IN: logging.server
|
IN: logging.server
|
||||||
|
|
||||||
: log-root ( -- string )
|
: log-root ( -- string )
|
||||||
|
@ -85,17 +85,16 @@ SYMBOL: log-files
|
||||||
log-root directory [ drop rotate-log ] assoc-each ;
|
log-root directory [ drop rotate-log ] assoc-each ;
|
||||||
|
|
||||||
: log-server-loop ( -- )
|
: log-server-loop ( -- )
|
||||||
[
|
receive unclip {
|
||||||
receive unclip {
|
{ "log-message" [ (log-message) ] }
|
||||||
{ "log-message" [ (log-message) ] }
|
{ "rotate-logs" [ drop (rotate-logs) ] }
|
||||||
{ "rotate-logs" [ drop (rotate-logs) ] }
|
{ "close-logs" [ drop (close-logs) ] }
|
||||||
{ "close-logs" [ drop (close-logs) ] }
|
} case log-server-loop ;
|
||||||
} case
|
|
||||||
] [ error. (close-logs) ] recover
|
|
||||||
log-server-loop ;
|
|
||||||
|
|
||||||
: log-server ( -- )
|
: log-server ( -- )
|
||||||
[ log-server-loop ] spawn "log-server" set-global ;
|
[ [ log-server-loop ] [ error. (close-logs) ] recover t ]
|
||||||
|
"Log server" spawn-server
|
||||||
|
"log-server" set-global ;
|
||||||
|
|
||||||
[
|
[
|
||||||
H{ } clone log-files set-global
|
H{ } clone log-files set-global
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
USING: alien alien.c-types arrays assocs byte-arrays inference
|
USING: alien alien.c-types arrays assocs byte-arrays inference
|
||||||
inference.transforms io io.binary io.streams.string kernel
|
inference.transforms io io.binary io.streams.string kernel
|
||||||
math math.parser namespaces parser prettyprint
|
math math.parser namespaces parser prettyprint
|
||||||
quotations sequences strings threads vectors
|
quotations sequences strings vectors
|
||||||
words macros math.functions ;
|
words macros math.functions ;
|
||||||
IN: pack
|
IN: pack
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
!
|
!
|
||||||
USING: cpu.8080 cpu.8080.emulator openal math alien.c-types
|
USING: cpu.8080 cpu.8080.emulator openal math alien.c-types
|
||||||
sequences kernel shuffle arrays io.files combinators ui.gestures
|
sequences kernel shuffle arrays io.files combinators ui.gestures
|
||||||
ui.gadgets ui.render opengl.gl system threads concurrency match
|
ui.gadgets ui.render opengl.gl system threads match
|
||||||
ui byte-arrays combinators.lib ;
|
ui byte-arrays combinators.lib ;
|
||||||
IN: space-invaders
|
IN: space-invaders
|
||||||
|
|
||||||
|
@ -353,9 +353,10 @@ M: space-invaders update-video ( value addr cpu -- )
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
M: invaders-gadget graft* ( gadget -- )
|
M: invaders-gadget graft* ( gadget -- )
|
||||||
dup invaders-gadget-cpu init-sounds
|
dup invaders-gadget-cpu init-sounds
|
||||||
[ f swap set-invaders-gadget-quit? ] keep
|
f over set-invaders-gadget-quit?
|
||||||
[ millis swap invaders-process ] spawn 2drop ;
|
[ millis swap invaders-process ] curry
|
||||||
|
"Space invaders" spawn drop ;
|
||||||
|
|
||||||
M: invaders-gadget ungraft* ( gadget -- )
|
M: invaders-gadget ungraft* ( gadget -- )
|
||||||
t swap set-invaders-gadget-quit? ;
|
t swap set-invaders-gadget-quit? ;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
USING: arrays assocs classes combinators sequences.private
|
USING: arrays assocs classes combinators sequences.private
|
||||||
continuations continuations.private generic hashtables io kernel
|
continuations continuations.private generic hashtables io kernel
|
||||||
kernel.private math namespaces namespaces.private prettyprint
|
kernel.private math namespaces namespaces.private prettyprint
|
||||||
quotations sequences splitting strings concurrency.threads
|
quotations sequences splitting strings threads
|
||||||
vectors words ;
|
vectors words ;
|
||||||
IN: tools.interpreter
|
IN: tools.interpreter
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! 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.
|
||||||
IN: tools.threads
|
IN: tools.threads
|
||||||
USING: concurrency.threads kernel prettyprint prettyprint.config
|
USING: threads kernel prettyprint prettyprint.config
|
||||||
io io.styles sequences assocs namespaces sorting ;
|
io io.styles sequences assocs namespaces sorting ;
|
||||||
|
|
||||||
: thread. ( thread -- )
|
: thread. ( thread -- )
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
USING: arrays assocs combinators continuations documents
|
USING: arrays assocs combinators continuations documents
|
||||||
ui.tools.workspace hashtables io io.styles kernel math
|
ui.tools.workspace hashtables io io.styles kernel math
|
||||||
math.vectors models namespaces parser prettyprint quotations
|
math.vectors models namespaces parser prettyprint quotations
|
||||||
sequences sequences.lib strings concurrency.threads listener
|
sequences sequences.lib strings threads listener
|
||||||
tuples ui.commands ui.gadgets ui.gadgets.editors
|
tuples ui.commands ui.gadgets ui.gadgets.editors
|
||||||
ui.gadgets.presentations ui.gadgets.worlds ui.gestures
|
ui.gadgets.presentations ui.gadgets.worlds ui.gestures
|
||||||
definitions ;
|
definitions ;
|
||||||
|
@ -88,12 +88,12 @@ M: interactor model-changed
|
||||||
] unless drop ;
|
] unless drop ;
|
||||||
|
|
||||||
: interactor-yield ( interactor -- obj )
|
: interactor-yield ( interactor -- obj )
|
||||||
dup gadget-graft-state first [
|
! dup gadget-graft-state first [
|
||||||
f over set-interactor-busy?
|
f over set-interactor-busy?
|
||||||
[ set-interactor-thread ] curry suspend
|
[ set-interactor-thread ] curry suspend ;
|
||||||
] [
|
! ] [
|
||||||
drop f
|
! drop f
|
||||||
] if ;
|
! ] if ;
|
||||||
|
|
||||||
M: interactor stream-readln
|
M: interactor stream-readln
|
||||||
[ interactor-yield ] keep interactor-finish ?first ;
|
[ interactor-yield ] keep interactor-finish ?first ;
|
||||||
|
|
|
@ -6,7 +6,7 @@ kernel models namespaces parser quotations sequences ui.commands
|
||||||
ui.gadgets ui.gadgets.editors ui.gadgets.labelled
|
ui.gadgets ui.gadgets.editors ui.gadgets.labelled
|
||||||
ui.gadgets.panes ui.gadgets.buttons ui.gadgets.scrollers
|
ui.gadgets.panes ui.gadgets.buttons ui.gadgets.scrollers
|
||||||
ui.gadgets.tracks ui.gestures ui.operations vocabs words
|
ui.gadgets.tracks ui.gestures ui.operations vocabs words
|
||||||
prettyprint listener debugger concurrency.threads ;
|
prettyprint listener debugger threads ;
|
||||||
IN: ui.tools.listener
|
IN: ui.tools.listener
|
||||||
|
|
||||||
TUPLE: listener-gadget input output stack ;
|
TUPLE: listener-gadget input output stack ;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: arrays assocs ui.tools.listener ui.tools.traceback
|
USING: arrays assocs ui.tools.listener ui.tools.traceback
|
||||||
ui.tools.workspace inspector kernel models namespaces
|
ui.tools.workspace inspector kernel models namespaces
|
||||||
prettyprint quotations sequences concurrency.threads
|
prettyprint quotations sequences threads
|
||||||
tools.interpreter ui.commands ui.gadgets ui.gadgets.labelled
|
tools.interpreter ui.commands ui.gadgets ui.gadgets.labelled
|
||||||
ui.gadgets.tracks ui.gestures ui.gadgets.buttons
|
ui.gadgets.tracks ui.gestures ui.gadgets.buttons
|
||||||
ui.gadgets.panes prettyprint.config prettyprint.backend
|
ui.gadgets.panes prettyprint.config prettyprint.backend
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2006, 2007 Slava Pestov.
|
! Copyright (C) 2006, 2007 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: arrays assocs io kernel math models namespaces
|
USING: arrays assocs io kernel math models namespaces
|
||||||
prettyprint dlists sequences concurrency.threads sequences words
|
prettyprint dlists sequences threads sequences words
|
||||||
timers debugger ui.gadgets ui.gadgets.worlds ui.gadgets.tracks
|
timers debugger ui.gadgets ui.gadgets.worlds ui.gadgets.tracks
|
||||||
ui.gestures ui.backend ui.render continuations init combinators
|
ui.gestures ui.backend ui.render continuations init combinators
|
||||||
hashtables ;
|
hashtables ;
|
||||||
|
|
|
@ -5,7 +5,7 @@ ui.backend ui.clipboards ui.gadgets.worlds ui.gestures io kernel
|
||||||
math math.vectors namespaces prettyprint sequences strings
|
math math.vectors namespaces prettyprint sequences strings
|
||||||
vectors words windows.kernel32 windows.gdi32 windows.user32
|
vectors words windows.kernel32 windows.gdi32 windows.user32
|
||||||
windows.opengl32 windows.messages windows.types windows.nt
|
windows.opengl32 windows.messages windows.types windows.nt
|
||||||
windows concurrency.threads timers libc combinators
|
windows threads timers libc combinators
|
||||||
continuations command-line shuffle opengl ui.render unicode.case
|
continuations command-line shuffle opengl ui.render unicode.case
|
||||||
ascii math.bitfields ;
|
ascii math.bitfields ;
|
||||||
IN: ui.windows
|
IN: ui.windows
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
USING: concurrency.threads io.files io.monitors init kernel
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
tools.browser ;
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: threads io.files io.monitors init kernel
|
||||||
|
tools.browser namespaces continuations ;
|
||||||
IN: vocabs.monitor
|
IN: vocabs.monitor
|
||||||
|
|
||||||
! Use file system change monitoring to flush the tags/authors
|
! Use file system change monitoring to flush the tags/authors
|
||||||
! cache
|
! cache
|
||||||
: (monitor-thread) ( monitor -- )
|
SYMBOL: vocab-monitor
|
||||||
dup next-change 2drop reset-cache (monitor-thread) ;
|
|
||||||
|
|
||||||
: monitor-thread ( -- )
|
: monitor-thread ( -- )
|
||||||
"" resource-path t <monitor> (monitor-thread) ;
|
vocab-monitor get-global next-change 2drop reset-cache ;
|
||||||
|
|
||||||
: start-monitor-thread
|
: start-monitor-thread
|
||||||
#! Silently ignore errors during monitor creation since
|
#! Silently ignore errors during monitor creation since
|
||||||
#! monitors are not supported on all platforms.
|
#! monitors are not supported on all platforms.
|
||||||
[ monitor-thread ] "Vocabulary monitor" spawn drop ;
|
[
|
||||||
|
"" resource-path t <monitor> vocab-monitor set-global
|
||||||
|
[ monitor-thread t ] "Vocabulary monitor" spawn-server drop
|
||||||
|
] [ drop ] recover ;
|
||||||
|
|
||||||
[ start-monitor-thread ] "vocabs.monitor" add-init-hook
|
[ start-monitor-thread ] "vocabs.monitor" add-init-hook
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
USING: sequences rss arrays concurrency kernel sorting
|
USING: sequences rss arrays concurrency.futures kernel sorting
|
||||||
html.elements io assocs namespaces math threads vocabs html
|
html.elements io assocs namespaces math threads
|
||||||
furnace http.server.templating calendar math.parser splitting
|
vocabs html furnace http.server.templating calendar math.parser
|
||||||
continuations debugger system http.server.responders
|
splitting continuations debugger system http.server.responders
|
||||||
xml.writer prettyprint logging ;
|
xml.writer prettyprint logging ;
|
||||||
IN: webapps.planet
|
IN: webapps.planet
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue