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

Last change on this file since 36210 was 36210, checked in by Kon Lovett, 16 months ago

rm deprecated per C4

File size: 8.5 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(define (consumer ch)
202  (make-thread
203    (lambda ()
204      (let loop ()
205        (print (current-thread) ": reading " (mailbox-receive! ch))
206        (loop) ) ) ) )
207
208(define ch (make-mailbox))
209(thread-start! (consumer ch))
210(for-each
211  (lambda (x)
212    (print (current-thread) ": writing " x)
213    (mailbox-send! ch x) )
214  '(33 44 55 hello) )
215</enscript>
216
217
218== Notes
219
220* Cannot wait with timeout on the primordial thread. So {{mailbox-wait!}},
221{{mailbox-receive!}}, and {{mailbox-cursor-next}} must not be used with a
222timeout value when the {{(current-thread)}} is the
223{{##sys#primordial-thread}}.
224
225* A "deadlock" situation is possible when using {{mailbox-wait!}},
226{{mailbox-receive!}}, or {{mailbox-cursor-next}} should there be no other
227threads "runnable." The problem is when the mailbox is empty the
228current-thread is suspended (indefinite block). When the scheduler looks for
229the next ready thread and one is not available it signals "deadlock." Using a
230{{TIMEOUT}} will allow the calling thread to unblock eventually.
231
232* A mailbox-cursor must live in an environment where mailbox entries are added
233and removed asynchronously. The cursor does '''not''' see a snapshot of the
234mailbox. The current state of the mailbox is queried.
235
236== Author
237
238[[/users/felix winkelmann|felix winkelmann]]
239
240[[/users/kon lovett|Kon Lovett]]
241
242
243== Requirements
244
245[[check-errors]]
246[[condition-utils]]
247[[record-variants]]
248
249
250== Version history
251
252; 3.0.0 : CHICKEN 5 release.
253; 2.3.1 : Fix name type.
254; 2.3.0 : Add types.
255; 2.2.3 :
256; 2.2.2 : Expand {{mailbox-timeout-condition}}.
257; 2.2.1 :
258; 2.2.0 : Included ''inline-type-checks.scm'' so all includes are egg-local.
259; 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.
260; 2.1.2 :
261; 2.1.1 :
262; 2.1.0 : Needs "check-errors" extension.
263; 2.0.0 : Port to hygienic Chicken.
264
265
266== License
267
268Copyright (c) 2003, Felix L. Winkelmann
269All rights reserved.
270
271Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
272conditions are met:
273
274  Redistributions of source code must retain the above copyright notice, this list of conditions and the following
275    disclaimer.
276  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
277    disclaimer in the documentation and/or other materials provided with the distribution.
278  Neither the name of the author nor the names of its contributors may be used to endorse or promote
279    products derived from this software without specific prior written permission.
280
281THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
282OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
283AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
284CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
285CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
286SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
287THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
288OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
289POSSIBILITY OF SUCH DAMAGE.
Note: See TracBrowser for help on using the repository browser.