]> gitweb.factorcode.org Git - factor.git/blob - extra/concurrency/mailboxes/mailboxes.factor
Merge branch 'master' of git://factorcode.org/git/factor
[factor.git] / extra / concurrency / mailboxes / mailboxes.factor
1 ! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.\r
2 ! See http://factorcode.org/license.txt for BSD license.\r
3 IN: concurrency.mailboxes\r
4 USING: dlists dequeues threads sequences continuations\r
5 destructors namespaces random math quotations words kernel\r
6 arrays assocs init system concurrency.conditions accessors\r
7 debugger ;\r
8 \r
9 TUPLE: mailbox threads data disposed ;\r
10 \r
11 M: mailbox dispose* threads>> notify-all ;\r
12 \r
13 : <mailbox> ( -- mailbox )\r
14     <dlist> <dlist> f mailbox boa ;\r
15 \r
16 : mailbox-empty? ( mailbox -- bool )\r
17     data>> dequeue-empty? ;\r
18 \r
19 : mailbox-put ( obj mailbox -- )\r
20     [ data>> push-front ]\r
21     [ threads>> notify-all ] bi yield ;\r
22 \r
23 : wait-for-mailbox ( mailbox timeout -- )\r
24     >r threads>> r> "mailbox" wait ;\r
25 \r
26 : block-unless-pred ( mailbox timeout pred: ( message -- ? ) -- )\r
27     pick check-disposed\r
28     pick data>> over dlist-contains? [\r
29         3drop\r
30     ] [\r
31         >r 2dup wait-for-mailbox r> block-unless-pred\r
32     ] if ; inline recursive\r
33 \r
34 : block-if-empty ( mailbox timeout -- mailbox )\r
35     over check-disposed\r
36     over mailbox-empty? [\r
37         2dup wait-for-mailbox block-if-empty\r
38     ] [\r
39         drop\r
40     ] if ;\r
41 \r
42 : mailbox-peek ( mailbox -- obj )\r
43     data>> peek-back ;\r
44 \r
45 : mailbox-get-timeout ( mailbox timeout -- obj )\r
46     block-if-empty data>> pop-back ;\r
47 \r
48 : mailbox-get ( mailbox -- obj )\r
49     f mailbox-get-timeout ;\r
50 \r
51 : mailbox-get-all-timeout ( mailbox timeout -- array )\r
52     block-if-empty\r
53     [ dup mailbox-empty? ]\r
54     [ dup data>> pop-back ]\r
55     [ ] produce nip ;\r
56 \r
57 : mailbox-get-all ( mailbox -- array )\r
58     f mailbox-get-all-timeout ;\r
59 \r
60 : while-mailbox-empty ( mailbox quot -- )\r
61     [ [ mailbox-empty? ] curry ] dip [ ] while ; inline\r
62 \r
63 : mailbox-get-timeout? ( mailbox timeout pred -- obj )\r
64     3dup block-unless-pred\r
65     nip >r data>> r> delete-node-if ; inline\r
66 \r
67 : mailbox-get? ( mailbox pred -- obj )\r
68     f swap mailbox-get-timeout? ; inline\r
69 \r
70 : wait-for-close-timeout ( mailbox timeout -- )\r
71     over disposed>>\r
72     [ 2drop ] [ 2dup wait-for-mailbox wait-for-close-timeout ] if ;\r
73 \r
74 : wait-for-close ( mailbox -- )\r
75     f wait-for-close-timeout ;\r
76 \r
77 TUPLE: linked-error error thread ;\r
78 \r
79 M: linked-error error.\r
80     [ thread>> error-in-thread. ] [ error>> error. ] bi ;\r
81 \r
82 C: <linked-error> linked-error\r
83 \r
84 : ?linked ( message -- message )\r
85     dup linked-error? [ rethrow ] when ;\r
86 \r
87 TUPLE: linked-thread < thread supervisor ;\r
88 \r
89 M: linked-thread error-in-thread\r
90     [ <linked-error> ] [ supervisor>> ] bi mailbox-put ;\r
91 \r
92 : <linked-thread> ( quot name mailbox -- thread' )\r
93     >r linked-thread new-thread r> >>supervisor ;\r
94 \r
95 : spawn-linked-to ( quot name mailbox -- thread )\r
96     <linked-thread> [ (spawn) ] keep ;\r