source: project/wiki/eggref/5/mailbox @ 36211

Last change on this file since 36211 was 36211, checked in by Kon Lovett, 14 months ago

fix example

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