factor/basis/concurrency/messaging/messaging.factor

89 lines
2.3 KiB
Factor
Raw Normal View History

2008-02-18 06:07:40 -05:00
! 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
2008-02-18 06:07:40 -05:00
! concurrency.
USING: kernel threads concurrency.mailboxes continuations
namespaces assocs random ;
2008-02-18 06:07:40 -05:00
IN: concurrency.messaging
2008-03-11 20:51:58 -04:00
GENERIC: send ( message thread -- )
2008-02-18 06:07:40 -05:00
2008-02-18 08:30:16 -05:00
: mailbox-of ( thread -- mailbox )
dup thread-mailbox [ ] [
<mailbox> dup rot set-thread-mailbox
] ?if ;
2008-02-18 06:07:40 -05:00
M: thread send ( message thread -- )
2008-02-21 00:13:31 -05:00
check-registered mailbox-of mailbox-put ;
2008-02-18 06:07:40 -05:00
2008-06-08 16:32:55 -04:00
: my-mailbox ( -- mailbox ) self mailbox-of ;
2008-02-18 06:07:40 -05:00
: receive ( -- message )
my-mailbox mailbox-get ?linked ;
: receive-timeout ( timeout -- message )
my-mailbox swap mailbox-get-timeout ?linked ;
2008-02-18 06:07:40 -05:00
: receive-if ( pred -- message )
2008-03-20 21:14:07 -04:00
my-mailbox swap mailbox-get? ?linked ; inline
2008-03-20 21:14:07 -04:00
: receive-if-timeout ( timeout pred -- message )
my-mailbox -rot mailbox-get-timeout? ?linked ; inline
2008-02-18 06:07:40 -05:00
: rethrow-linked ( error process supervisor -- )
2008-02-27 23:23:01 -05:00
>r <linked-error> r> send ;
2008-02-18 06:07:40 -05:00
: spawn-linked ( quot name -- thread )
my-mailbox spawn-linked-to ;
2008-02-18 06:07:40 -05:00
TUPLE: synchronous data sender tag ;
: <synchronous> ( data -- sync )
self 256 random-bits synchronous boa ;
2008-02-18 06:07:40 -05:00
TUPLE: reply data tag ;
: <reply> ( data synchronous -- reply )
synchronous-tag \ reply boa ;
2008-02-18 06:07:40 -05:00
: synchronous-reply? ( response synchronous -- ? )
over reply?
[ >r reply-tag r> synchronous-tag = ]
[ 2drop f ] if ;
2008-02-18 06:07:40 -05:00
: send-synchronous ( message thread -- reply )
2008-02-20 00:17:59 -05:00
dup self eq? [
"Cannot synchronous send to myself" throw
] [
>r <synchronous> dup r> send
[ synchronous-reply? ] curry receive-if
reply-data
2008-02-20 00:17:59 -05:00
] if ;
2008-02-18 06:07:40 -05:00
: reply-synchronous ( message synchronous -- )
2008-02-18 08:30:16 -05:00
[ <reply> ] keep synchronous-sender send ;
2008-02-18 10:08:59 -05:00
2008-02-20 00:17:59 -05:00
: handle-synchronous ( quot -- )
receive [
synchronous-data swap call
] keep reply-synchronous ; inline
2008-02-18 10:08:59 -05:00
<PRIVATE
: registered-processes ( -- hash )
\ registered-processes get-global ;
2008-02-18 10:08:59 -05:00
PRIVATE>
: register-process ( name process -- )
swap registered-processes set-at ;
2008-02-18 10:08:59 -05:00
: unregister-process ( name -- )
registered-processes delete-at ;
2008-02-18 10:08:59 -05:00
: get-process ( name -- process )
dup registered-processes at [ ] [ thread ] ?if ;
2008-02-18 10:08:59 -05:00
\ registered-processes global [ H{ } assoc-like ] change-at