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

Last change on this file since 36581 was 36581, checked in by Kon Lovett, 2 years ago

rel 3.3.0

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