! 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 [ ] [ 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 r> send ; : spawn-linked ( quot name -- thread ) my-mailbox spawn-linked-to ; TUPLE: synchronous data sender tag ; : ( data -- sync ) self 256 random-bits synchronous boa ; TUPLE: reply data tag ; : ( 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 dup r> send [ synchronous-reply? ] curry receive-if reply-data ] if ; : reply-synchronous ( message synchronous -- ) [ ] keep synchronous-sender send ; : handle-synchronous ( quot -- ) receive [ synchronous-data swap call ] keep reply-synchronous ; inline : 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