source: project/wiki/eggref/4/mailbox @ 35028

Last change on this file since 35028 was 35028, checked in by Kon Lovett, 20 months ago

rel 2.2.3

File size: 8.9 KB
Line 
1[[tags: egg]]
2
3
4== mailbox
5
6[[toc:]]
7
8
9== Documentation
10
11Thread-safe queues with timeout.
12
13=== mailbox-timeout-condition?
14
15<procedure>(mailbox-timeout-condition? OBJ) => boolean</procedure>
16
17Is the {{OBJ}} a mailbox timeout condition?
18
19A mailbox timeout condition is a composite condition of {{'exn}},
20{{'mailbox}}, and {{'timeout}} conditions.
21
22The {{'exn}} condition has properties of {{'location}}, {{'message}},
23{{'arguments}}, and {{'call-chain}}.
24
25The {{'mailbox}} condition has properties of {{'box}}.
26
27The {{'timeout}} condition has properties of {{'time}}, and {{'value}}.
28
29The addition of the timeout properties as {{'exn}} {{'arguments}} is
30deprecated.
31
32=== mailbox-timeout-exception?
33
34<procedure>(mailbox-timeout-exception? OBJ) => boolean</procedure>
35
36Synonym of {{mailbox-timeout-condition?}}.
37
38=== make-mailbox
39
40<procedure>(make-mailbox [NAME]) => mailbox</procedure>
41
42Returns a new mailbox object.
43
44{{NAME}} is an optional object to identify this mailbox and defaults to
45{{(gensym 'mailbox)}}.
46
47=== mailbox?
48
49<procedure>(mailbox? OBJ) => boolean</procedure>
50
51Is the {{OBJ}} a {{mailbox}}?
52
53=== mailbox-name
54
55<procedure>(mailbox-name MAILBOX) => *</procedure>
56
57Returns the name of the {{MAILBOX}}.
58
59=== mailbox-empty?
60
61<procedure>(mailbox-empty? MAILBOX) => boolean</procedure>
62
63If there are no queued objects in the {{MAILBOX}}, then
64this procedure returns {{#t}}, otherwise it returns {{#f}}.
65
66=== mailbox-count
67
68<procedure>(mailbox-count MAILBOX) => integer</procedure>
69
70Returns the number of queued objects for the {{MAILBOX}}.
71
72=== mailbox-waiting?
73
74<procedure>(mailbox-waiting? MAILBOX) => boolean</procedure>
75
76Is any thread waiting for the {{MAILBOX}}?
77
78=== mailbox-waiters
79
80<procedure>(mailbox-waiters MAILBOX) => list</procedure>
81
82Returns a list of the threads waiting for the {{MAILBOX}}.
83
84=== mailbox-send!
85
86<procedure>(mailbox-send! MAILBOX OBJ)</procedure>
87
88Queues the data object {{OBJ}}. If any threads exist that are waiting
89for input on {{MAILBOX}}, the execution of the first one will be
90resumed. The data will be read out of a mailbox in the same order in
91which is written in (in FIFO manner).
92
93=== mailbox-receive!
94
95<procedure>(mailbox-receive! MAILBOX [TIMEOUT [DEFAULT]]) => *</procedure>
96
97If there is any data in the {{MAILBOX}}, then the first object will be
98removed and returned as the result. If the mailbox is currently empty,
99the current thread will suspended until data is available.
100
101{{TIMEOUT}} is a [[http://srfi.schemers.org/srfi-18/srfi-18.html|SRFI-18]]
102{{time}} object or the real number of seconds.
103
104Should {{TIMEOUT}} be specified and occur the {{DEFAULT}}, if supplied, will be
105returned. Otherwise a mailbox timeout exception will be signaled for the
106calling thread. The {{DEFAULT}} value cannot be {{(void)}}.
107
108=== mailbox-wait!
109
110<procedure>(mailbox-wait! MAILBOX [TIMEOUT])</procedure>
111
112Similar to {{mailbox-receive!}}, but does not remove the received
113result from the queue of pending data.
114
115{{TIMEOUT}} is a [[http://srfi.schemers.org/srfi-18/srfi-18.html|SRFI-18]]
116{{time}} object or the real number of seconds.
117
118Should {{TIMEOUT}} be specified and occur a mailbox timeout exception
119will be signaled for the calling thread.
120
121=== mailbox-push-back!
122
123<procedure>(mailbox-push-back! MAILBOX OBJ)</procedure>
124
125Pushes the data object {{OBJ}} into the first position of a mailbox.
126
127=== mailbox-push-back-list!
128
129<procedure>(mailbox-push-back-list! MAILBOX OBJS)</procedure>
130
131Pushes the list of objects {{OBJS}} back into the mailbox, so that {{(car
132OBJS)}} becomes the next receivable item.
133
134=== make-mailbox-cursor
135
136<procedure>(make-mailbox-cursor MAILBOX) => mailbox-cursor</procedure>
137
138Returns an object which can enumerate a mailbox.
139
140Multiple cursors can scan, and mutate, the same mailbox.
141
142=== mailbox-cursor?
143
144<procedure>(mailbox-cursor? OBJ) => boolean</procedure>
145
146Is the {{OBJ}} a {{mailbox-cursor}}?
147
148=== mailbox-cursor-mailbox
149
150<procedure>(mailbox-cursor-mailbox MAILBOX-CURSOR) => mailbox</procedure>
151
152Returns the mailbox object associated with the mailbox cursor.
153
154=== mailbox-cursor-next
155
156<procedure>(mailbox-cursor-next MAILBOX-CURSOR [TIMEOUT [DEFAULT]]) => *</procedure>
157
158Returns the next object in the mailbox queue, waiting if necessary.
159
160The mailbox queue is scanned from oldest to newest.
161
162{{TIMEOUT}} is a [[http://srfi.schemers.org/srfi-18/srfi-18.html|SRFI-18]]
163{{time}} object or the real number of seconds.
164
165Should {{TIMEOUT}} be specified and occur the {{DEFAULT}}, if supplied, will be
166returned. Otherwise a mailbox timeout exception will be signaled for the
167calling thread. The {{DEFAULT}} value cannot be {{(void)}}.
168
169=== mailbox-cursor-rewind
170
171<procedure>(mailbox-cursor-rewind MAILBOX-CURSOR)</procedure>
172
173Position the cursor at the oldest message in the mailbox.
174
175=== mailbox-cursor-extract-and-rewind
176
177<procedure>(mailbox-cursor-extract-and-rewind MAILBOX-CURSOR)</procedure>
178
179Remove from the associated mailbox queue the last object returned by
180{{mailbox-cursor-next}} and position the cursor at the oldest message in the
181mailbox.
182
183The extraction is not performed without a previous call to
184{{mailbox-cursor-next}}.
185
186=== mailbox-cursor-rewound?
187
188<procedure>(mailbox-cursor-rewound? MAILBOX-CURSOR) => boolean</procedure>
189
190Is the {{MAILBOX-CURSOR}} positioned at the start of the mailbox queue?
191
192=== mailbox-cursor-unwound?
193
194<procedure>(mailbox-cursor-unwound? MAILBOX-CURSOR) => boolean</procedure>
195
196Is the {{MAILBOX-CURSOR}} positioned at the end of the mailbox queue?
197
198
199== Usage
200
201<enscript language=scheme>
202(require-extension mailbox)
203</enscript>
204
205or
206
207<enscript language=scheme>
208(require-library mailbox)
209...
210(import mailbox)
211</enscript>
212
213
214== Examples
215
216<enscript language=scheme>
217(define (consumer ch)
218  (make-thread
219    (lambda ()
220      (let loop ()
221        (print (current-thread) ": reading " (mailbox-receive! ch))
222        (loop) ) ) ) )
223
224(define ch (make-mailbox))
225(thread-start! (consumer ch))
226(for-each
227  (lambda (x)
228    (print (current-thread) ": writing " x)
229    (mailbox-send! ch x) )
230  '(33 44 55 hello) )
231</enscript>
232
233
234== Notes
235
236* Cannot wait with timeout on the primordial thread. So {{mailbox-wait!}},
237{{mailbox-receive!}}, and {{mailbox-cursor-next}} must not be used with a
238timeout value when the {{(current-thread)}} is the
239{{##sys#primordial-thread}}.
240
241* A "deadlock" situation is possible when using {{mailbox-wait!}},
242{{mailbox-receive!}}, or {{mailbox-cursor-next}} should there be no other
243threads "runnable." The problem is when the mailbox is empty the
244current-thread is suspended (indefinite block). When the scheduler looks for
245the next ready thread and one is not available it signals "deadlock." Using a
246{{TIMEOUT}} will allow the calling thread to unblock eventually.
247
248* A mailbox-cursor must live in an environment where mailbox entries are added
249and removed asynchronously. The cursor does '''not''' see a snapshot of the
250mailbox. The current state of the mailbox is queried.
251
252* {{mailbox-timeout-exception?}} will be deprecated.
253
254== Author
255
256[[/users/felix winkelmann|felix winkelmann]]
257
258[[/users/kon lovett|Kon Lovett]]
259
260
261== Requirements
262
263[[check-errors]]
264[[condition-utils]]
265[[record-variants]]
266[[setup-helper]]
267
268
269== Version history
270
271; 2.2.3 :
272; 2.2.2 : Expand {{mailbox-timeout-condition}}.
273; 2.2.1 :
274; 2.2.0 : Included ''inline-type-checks.scm'' so all includes are egg-local.
275; 2.1.3 : Fix for resuming a thread when mailbox empty; reported by Jeronimo Pellegrini. Added {{mailbox-cursor-unwound?}}. The {{mailbox-name}} can be an arbitrary Scheme object.
276; 2.1.2 :
277; 2.1.1 :
278; 2.1.0 : Needs "check-errors" extension.
279; 2.0.0 : Port to hygienic Chicken.
280
281
282== License
283
284Copyright (c) 2003, Felix L. Winkelmann
285All rights reserved.
286
287Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
288conditions are met:
289
290  Redistributions of source code must retain the above copyright notice, this list of conditions and the following
291    disclaimer.
292  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
293    disclaimer in the documentation and/or other materials provided with the distribution.
294  Neither the name of the author nor the names of its contributors may be used to endorse or promote
295    products derived from this software without specific prior written permission.
296
297THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
298OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
299AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
300CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
301CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
302SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
303THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
304OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
305POSSIBILITY OF SUCH DAMAGE.
Note: See TracBrowser for help on using the repository browser.