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.
|
2008-02-22 00:47:06 -05:00
|
|
|
USING: kernel threads concurrency.mailboxes continuations
|
2009-08-30 11:26:23 -04:00
|
|
|
namespaces assocs accessors summary fry calendar math sequences ;
|
2008-02-18 06:07:40 -05:00
|
|
|
IN: concurrency.messaging
|
|
|
|
|
|
2009-08-30 11:26:23 -04:00
|
|
|
TUPLE: envelope data sender tag expiry ;
|
|
|
|
|
|
|
|
|
|
<PRIVATE
|
|
|
|
|
|
|
|
|
|
: new-envelope ( data class -- envelope )
|
|
|
|
|
new swap >>data self >>sender ;
|
|
|
|
|
|
|
|
|
|
: <envelope> ( data -- envelope )
|
|
|
|
|
dup envelope?
|
|
|
|
|
[ envelope new-envelope ] unless ;
|
|
|
|
|
|
|
|
|
|
: expired? ( message -- ? )
|
|
|
|
|
dup envelope?
|
|
|
|
|
[ expiry>>
|
|
|
|
|
[ now (time-) 0 < ]
|
|
|
|
|
[ f ] if*
|
|
|
|
|
] [ drop f ] if ; inline
|
|
|
|
|
|
|
|
|
|
: if-expired ( message quot -- message )
|
|
|
|
|
[ dup expired? ] dip
|
|
|
|
|
'[ drop _ call( -- message ) ] [ ] if ; inline
|
|
|
|
|
|
|
|
|
|
PRIVATE>
|
|
|
|
|
|
2008-03-11 20:51:58 -04:00
|
|
|
GENERIC: send ( message thread -- )
|
2008-02-18 06:07:40 -05:00
|
|
|
|
2009-08-30 11:26:23 -04:00
|
|
|
GENERIC: send-timeout ( timeout message thread -- )
|
|
|
|
|
|
2008-02-18 08:30:16 -05:00
|
|
|
: mailbox-of ( thread -- mailbox )
|
2008-08-30 13:35:00 -04:00
|
|
|
dup mailbox>> [ ] [
|
2008-08-30 14:06:06 -04:00
|
|
|
<mailbox> [ >>mailbox drop ] keep
|
2008-02-18 08:30:16 -05:00
|
|
|
] ?if ;
|
|
|
|
|
|
2008-02-18 06:07:40 -05:00
|
|
|
M: thread send ( message thread -- )
|
2009-08-30 11:26:23 -04:00
|
|
|
[ <envelope> ] dip
|
2008-02-21 00:13:31 -05:00
|
|
|
check-registered mailbox-of mailbox-put ;
|
2008-02-18 06:07:40 -05:00
|
|
|
|
2009-08-30 11:26:23 -04:00
|
|
|
M: thread send-timeout ( timeout message thread -- )
|
|
|
|
|
[ <envelope> swap hence >>expiry ] dip send ;
|
|
|
|
|
|
2008-06-08 16:32:55 -04:00
|
|
|
: my-mailbox ( -- mailbox ) self mailbox-of ;
|
2008-02-18 06:07:40 -05:00
|
|
|
|
2009-08-30 11:26:23 -04:00
|
|
|
: (receive) ( -- message )
|
|
|
|
|
my-mailbox mailbox-get ?linked
|
|
|
|
|
[ (receive) ] if-expired ;
|
|
|
|
|
|
2008-02-18 06:07:40 -05:00
|
|
|
: receive ( -- message )
|
2009-08-30 11:26:23 -04:00
|
|
|
(receive) data>> ;
|
|
|
|
|
|
|
|
|
|
: (receive-timeout) ( timeout -- message )
|
|
|
|
|
[ my-mailbox ] dip
|
|
|
|
|
[ mailbox-get-timeout ?linked ] keep
|
|
|
|
|
'[ _ (receive-timeout) ] if-expired ; inline
|
2008-02-22 00:47:06 -05:00
|
|
|
|
|
|
|
|
: receive-timeout ( timeout -- message )
|
2009-08-30 11:26:23 -04:00
|
|
|
(receive-timeout) data>> ;
|
|
|
|
|
|
|
|
|
|
: (receive-if) ( pred -- message )
|
|
|
|
|
[ my-mailbox ] dip
|
|
|
|
|
[ mailbox-get? ?linked ] keep
|
|
|
|
|
'[ _ (receive-if) ] if-expired ; inline
|
2008-02-18 06:07:40 -05:00
|
|
|
|
|
|
|
|
: receive-if ( pred -- message )
|
2009-08-30 11:26:23 -04:00
|
|
|
[ data>> ] prepend (receive-if) data>> ; inline
|
|
|
|
|
|
|
|
|
|
: (receive-if-timeout) ( timeout pred -- message )
|
|
|
|
|
[ my-mailbox ] 2dip
|
|
|
|
|
[ mailbox-get-timeout? ?linked ] 2keep
|
|
|
|
|
'[ _ _ (receive-if-timeout) ] if-expired ; inline
|
2008-02-22 00:47:06 -05:00
|
|
|
|
2008-03-20 21:14:07 -04:00
|
|
|
: receive-if-timeout ( timeout pred -- message )
|
2009-08-30 11:26:23 -04:00
|
|
|
[ data>> ] prepend
|
|
|
|
|
(receive-if-timeout) data>> ; inline
|
2008-02-18 06:07:40 -05:00
|
|
|
|
2008-02-18 17:20:18 -05:00
|
|
|
: rethrow-linked ( error process supervisor -- )
|
2008-11-30 19:28:15 -05:00
|
|
|
[ <linked-error> ] dip send ;
|
2008-02-18 06:07:40 -05:00
|
|
|
|
|
|
|
|
: spawn-linked ( quot name -- thread )
|
2008-02-22 00:47:06 -05:00
|
|
|
my-mailbox spawn-linked-to ;
|
2008-02-18 06:07:40 -05:00
|
|
|
|
2009-08-30 11:26:23 -04:00
|
|
|
TUPLE: synchronous < envelope ;
|
2008-02-18 06:07:40 -05:00
|
|
|
|
|
|
|
|
: <synchronous> ( data -- sync )
|
2009-08-30 11:26:23 -04:00
|
|
|
synchronous new-envelope
|
|
|
|
|
synchronous counter >>tag ;
|
2008-02-18 06:07:40 -05:00
|
|
|
|
2009-08-30 11:26:23 -04:00
|
|
|
TUPLE: reply < envelope ;
|
2008-02-18 06:07:40 -05:00
|
|
|
|
|
|
|
|
: <reply> ( data synchronous -- reply )
|
2009-08-30 11:26:23 -04:00
|
|
|
[ reply new-envelope ] dip
|
|
|
|
|
tag>> >>tag ;
|
2008-02-18 06:07:40 -05:00
|
|
|
|
2008-02-22 00:47:06 -05:00
|
|
|
: synchronous-reply? ( response synchronous -- ? )
|
2008-11-30 19:28:15 -05:00
|
|
|
over reply? [ [ tag>> ] bi@ = ] [ 2drop f ] if ;
|
2008-02-22 00:47:06 -05:00
|
|
|
|
2008-09-15 11:30:06 -04:00
|
|
|
ERROR: cannot-send-synchronous-to-self message thread ;
|
|
|
|
|
|
|
|
|
|
M: cannot-send-synchronous-to-self summary
|
|
|
|
|
drop "Cannot synchronous send to myself" ;
|
|
|
|
|
|
2008-02-18 06:07:40 -05:00
|
|
|
: send-synchronous ( message thread -- reply )
|
2008-02-20 00:17:59 -05:00
|
|
|
dup self eq? [
|
2008-09-15 11:30:06 -04:00
|
|
|
cannot-send-synchronous-to-self
|
2008-02-20 00:17:59 -05:00
|
|
|
] [
|
2008-11-30 19:28:15 -05:00
|
|
|
[ <synchronous> dup ] dip send
|
2009-08-30 11:26:23 -04:00
|
|
|
'[ _ synchronous-reply? ] (receive-if) data>>
|
|
|
|
|
] if ;
|
2008-02-18 06:07:40 -05:00
|
|
|
|
2009-08-22 10:46:45 -04:00
|
|
|
: send-synchronous-timeout ( timeout message thread -- reply )
|
|
|
|
|
dup self eq? [
|
|
|
|
|
cannot-send-synchronous-to-self
|
|
|
|
|
] [
|
2009-08-30 11:26:23 -04:00
|
|
|
[ <synchronous> 2dup ] dip send-timeout
|
|
|
|
|
'[ _ synchronous-reply? ] (receive-if-timeout) data>>
|
2009-08-22 10:46:45 -04:00
|
|
|
] if ;
|
2009-08-30 11:26:23 -04:00
|
|
|
|
2008-02-18 06:07:40 -05:00
|
|
|
: reply-synchronous ( message synchronous -- )
|
2009-08-30 11:26:23 -04:00
|
|
|
dup expired?
|
|
|
|
|
[ 2drop ]
|
|
|
|
|
[ [ <reply> ] keep sender>> send ] if ;
|
|
|
|
|
|
2008-02-20 00:17:59 -05:00
|
|
|
: handle-synchronous ( quot -- )
|
2009-08-30 11:26:23 -04:00
|
|
|
(receive) [
|
2008-08-29 02:00:39 -04:00
|
|
|
data>> swap call
|
2008-02-20 00:17:59 -05:00
|
|
|
] keep reply-synchronous ; inline
|
|
|
|
|
|
2008-02-18 10:08:59 -05:00
|
|
|
<PRIVATE
|
|
|
|
|
|
2008-02-22 00:47:06 -05:00
|
|
|
: registered-processes ( -- hash )
|
|
|
|
|
\ registered-processes get-global ;
|
2008-02-18 10:08:59 -05:00
|
|
|
|
|
|
|
|
PRIVATE>
|
|
|
|
|
|
|
|
|
|
: register-process ( name process -- )
|
2008-02-22 00:47:06 -05:00
|
|
|
swap registered-processes set-at ;
|
2008-02-18 10:08:59 -05:00
|
|
|
|
|
|
|
|
: unregister-process ( name -- )
|
2008-02-22 00:47:06 -05:00
|
|
|
registered-processes delete-at ;
|
2008-02-18 10:08:59 -05:00
|
|
|
|
|
|
|
|
: get-process ( name -- process )
|
2008-02-22 00:47:06 -05:00
|
|
|
dup registered-processes at [ ] [ thread ] ?if ;
|
2008-02-18 10:08:59 -05:00
|
|
|
|
2009-02-10 17:16:12 -05:00
|
|
|
\ registered-processes [ H{ } clone ] initialize
|