89 lines
2.3 KiB
Factor
89 lines
2.3 KiB
Factor
|
! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.
|
||
|
! See http://factorcode.org/license.txt for BSD license.
|
||
|
!
|
||
|
! Concurrency library for Factor, based on Erlang/Termite style
|
||
|
! concurrency.
|
||
|
USING: kernel threads concurrency.mailboxes continuations
|
||
|
namespaces assocs random ;
|
||
|
IN: concurrency.messaging
|
||
|
|
||
|
GENERIC: send ( message thread -- )
|
||
|
|
||
|
: mailbox-of ( thread -- mailbox )
|
||
|
dup thread-mailbox [ ] [
|
||
|
<mailbox> dup rot set-thread-mailbox
|
||
|
] ?if ;
|
||
|
|
||
|
M: thread send ( message thread -- )
|
||
|
check-registered mailbox-of mailbox-put ;
|
||
|
|
||
|
: my-mailbox ( -- mailbox ) self mailbox-of ;
|
||
|
|
||
|
: receive ( -- message )
|
||
|
my-mailbox mailbox-get ?linked ;
|
||
|
|
||
|
: receive-timeout ( timeout -- message )
|
||
|
my-mailbox swap mailbox-get-timeout ?linked ;
|
||
|
|
||
|
: receive-if ( pred -- message )
|
||
|
my-mailbox swap mailbox-get? ?linked ; inline
|
||
|
|
||
|
: receive-if-timeout ( timeout pred -- message )
|
||
|
my-mailbox -rot mailbox-get-timeout? ?linked ; inline
|
||
|
|
||
|
: rethrow-linked ( error process supervisor -- )
|
||
|
>r <linked-error> r> send ;
|
||
|
|
||
|
: spawn-linked ( quot name -- thread )
|
||
|
my-mailbox spawn-linked-to ;
|
||
|
|
||
|
TUPLE: synchronous data sender tag ;
|
||
|
|
||
|
: <synchronous> ( data -- sync )
|
||
|
self 256 random-bits synchronous boa ;
|
||
|
|
||
|
TUPLE: reply data tag ;
|
||
|
|
||
|
: <reply> ( data synchronous -- reply )
|
||
|
synchronous-tag \ reply boa ;
|
||
|
|
||
|
: synchronous-reply? ( response synchronous -- ? )
|
||
|
over reply?
|
||
|
[ >r reply-tag r> synchronous-tag = ]
|
||
|
[ 2drop f ] if ;
|
||
|
|
||
|
: send-synchronous ( message thread -- reply )
|
||
|
dup self eq? [
|
||
|
"Cannot synchronous send to myself" throw
|
||
|
] [
|
||
|
>r <synchronous> dup r> send
|
||
|
[ synchronous-reply? ] curry receive-if
|
||
|
reply-data
|
||
|
] if ;
|
||
|
|
||
|
: reply-synchronous ( message synchronous -- )
|
||
|
[ <reply> ] keep synchronous-sender send ;
|
||
|
|
||
|
: handle-synchronous ( quot -- )
|
||
|
receive [
|
||
|
synchronous-data swap call
|
||
|
] keep reply-synchronous ; inline
|
||
|
|
||
|
<PRIVATE
|
||
|
|
||
|
: registered-processes ( -- hash )
|
||
|
\ registered-processes get-global ;
|
||
|
|
||
|
PRIVATE>
|
||
|
|
||
|
: register-process ( name process -- )
|
||
|
swap registered-processes set-at ;
|
||
|
|
||
|
: unregister-process ( name -- )
|
||
|
registered-processes delete-at ;
|
||
|
|
||
|
: get-process ( name -- process )
|
||
|
dup registered-processes at [ ] [ thread ] ?if ;
|
||
|
|
||
|
\ registered-processes global [ H{ } assoc-like ] change-at
|