1 ! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.
\r
2 ! See http://factorcode.org/license.txt for BSD license.
\r
4 ! Concurrency library for Factor, based on Erlang/Termite style
\r
6 USING: kernel threads concurrency.mailboxes continuations
\r
7 namespaces assocs random accessors summary ;
\r
8 IN: concurrency.messaging
\r
10 GENERIC: send ( message thread -- )
\r
12 : mailbox-of ( thread -- mailbox )
\r
14 <mailbox> [ >>mailbox drop ] keep
\r
17 M: thread send ( message thread -- )
\r
18 check-registered mailbox-of mailbox-put ;
\r
20 : my-mailbox ( -- mailbox ) self mailbox-of ;
\r
22 : receive ( -- message )
\r
23 my-mailbox mailbox-get ?linked ;
\r
25 : receive-timeout ( timeout -- message )
\r
26 my-mailbox swap mailbox-get-timeout ?linked ;
\r
28 : receive-if ( pred -- message )
\r
29 my-mailbox swap mailbox-get? ?linked ; inline
\r
31 : receive-if-timeout ( timeout pred -- message )
\r
32 my-mailbox -rot mailbox-get-timeout? ?linked ; inline
\r
34 : rethrow-linked ( error process supervisor -- )
\r
35 >r <linked-error> r> send ;
\r
37 : spawn-linked ( quot name -- thread )
\r
38 my-mailbox spawn-linked-to ;
\r
40 TUPLE: synchronous data sender tag ;
\r
42 : <synchronous> ( data -- sync )
\r
43 self 256 random-bits synchronous boa ;
\r
45 TUPLE: reply data tag ;
\r
47 : <reply> ( data synchronous -- reply )
\r
50 : synchronous-reply? ( response synchronous -- ? )
\r
52 [ >r tag>> r> tag>> = ]
\r
55 ERROR: cannot-send-synchronous-to-self message thread ;
\r
57 M: cannot-send-synchronous-to-self summary
\r
58 drop "Cannot synchronous send to myself" ;
\r
60 : send-synchronous ( message thread -- reply )
\r
62 cannot-send-synchronous-to-self
\r
64 >r <synchronous> dup r> send
\r
65 [ synchronous-reply? ] curry receive-if
\r
69 : reply-synchronous ( message synchronous -- )
\r
70 [ <reply> ] keep sender>> send ;
\r
72 : handle-synchronous ( quot -- )
\r
75 ] keep reply-synchronous ; inline
\r
79 : registered-processes ( -- hash )
\r
80 \ registered-processes get-global ;
\r
84 : register-process ( name process -- )
\r
85 swap registered-processes set-at ;
\r
87 : unregister-process ( name -- )
\r
88 registered-processes delete-at ;
\r
90 : get-process ( name -- process )
\r
91 dup registered-processes at [ ] [ thread ] ?if ;
\r
93 \ registered-processes global [ H{ } assoc-like ] change-at
\r