This file is indexed.

/usr/share/doc/racket/inside/threads.html is in racket-doc 6.1-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><title>10&nbsp;Threads</title><link rel="stylesheet" type="text/css" href="../scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="../racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../doc-site.css" title="default"/><script type="text/javascript" src="../scribble-common.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../doc-site.js"></script><script type="text/javascript" src="../local-redirect/local-redirect.js"></script><script type="text/javascript" src="../local-redirect/local-user-redirect.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="doc-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_0&quot;);">&#9660;</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">Inside:<span class="mywbr"> &nbsp;</span> Racket C API</a></td></tr></table></div><div class="tocviewsublisttop" style="display: block;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1&nbsp;</td><td><a href="overview.html" class="tocviewlink" data-pltdoc="x">Overview</a></td></tr><tr><td align="right">2&nbsp;</td><td><a href="embedding.html" class="tocviewlink" data-pltdoc="x">Embedding into a Program</a></td></tr><tr><td align="right">3&nbsp;</td><td><a href="Writing_Racket_Extensions.html" class="tocviewlink" data-pltdoc="x">Writing Racket Extensions</a></td></tr><tr><td align="right">4&nbsp;</td><td><a href="im_values_types.html" class="tocviewlink" data-pltdoc="x">Values and Types</a></td></tr><tr><td align="right">5&nbsp;</td><td><a href="im_memoryalloc.html" class="tocviewlink" data-pltdoc="x">Memory Allocation</a></td></tr><tr><td align="right">6&nbsp;</td><td><a href="im_env.html" class="tocviewlink" data-pltdoc="x">Namespaces and Modules</a></td></tr><tr><td align="right">7&nbsp;</td><td><a href="Procedures.html" class="tocviewlink" data-pltdoc="x">Procedures</a></td></tr><tr><td align="right">8&nbsp;</td><td><a href="Evaluation.html" class="tocviewlink" data-pltdoc="x">Evaluation</a></td></tr><tr><td align="right">9&nbsp;</td><td><a href="exceptions.html" class="tocviewlink" data-pltdoc="x">Exceptions and Escape Continuations</a></td></tr><tr><td align="right">10&nbsp;</td><td><a href="" class="tocviewselflink" data-pltdoc="x">Threads</a></td></tr><tr><td align="right">11&nbsp;</td><td><a href="config.html" class="tocviewlink" data-pltdoc="x">Parameterizations</a></td></tr><tr><td align="right">12&nbsp;</td><td><a href="contmarks.html" class="tocviewlink" data-pltdoc="x">Continuation Marks</a></td></tr><tr><td align="right">13&nbsp;</td><td><a href="im_encodings.html" class="tocviewlink" data-pltdoc="x">String Encodings</a></td></tr><tr><td align="right">14&nbsp;</td><td><a href="Bignums__Rationals__and_Complex_Numbers.html" class="tocviewlink" data-pltdoc="x">Bignums, Rationals, and Complex Numbers</a></td></tr><tr><td align="right">15&nbsp;</td><td><a href="Ports_and_the_Filesystem.html" class="tocviewlink" data-pltdoc="x">Ports and the Filesystem</a></td></tr><tr><td align="right">16&nbsp;</td><td><a href="Structures.html" class="tocviewlink" data-pltdoc="x">Structures</a></td></tr><tr><td align="right">17&nbsp;</td><td><a href="security.html" class="tocviewlink" data-pltdoc="x">Security Guards</a></td></tr><tr><td align="right">18&nbsp;</td><td><a href="Custodians.html" class="tocviewlink" data-pltdoc="x">Custodians</a></td></tr><tr><td align="right">19&nbsp;</td><td><a href="Subprocesses.html" class="tocviewlink" data-pltdoc="x">Subprocesses</a></td></tr><tr><td align="right">20&nbsp;</td><td><a href="Miscellaneous_Utilities.html" class="tocviewlink" data-pltdoc="x">Miscellaneous Utilities</a></td></tr><tr><td align="right"></td><td><a href="doc-index.html" class="tocviewlink" data-pltdoc="x">Index</a></td></tr></table></div></div><div class="tocviewlist"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_1&quot;);">&#9658;</a></td><td>10&nbsp;</td><td><a href="" class="tocviewselflink" data-pltdoc="x">Threads</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">10.1&nbsp;</td><td><a href="#%28part._.Integration_with_.Threads%29" class="tocviewlink" data-pltdoc="x">Integration with Threads</a></td></tr><tr><td align="right">10.2&nbsp;</td><td><a href="#%28part._usefuel%29" class="tocviewlink" data-pltdoc="x">Allowing Thread Switches</a></td></tr><tr><td align="right">10.3&nbsp;</td><td><a href="#%28part._threadblock%29" class="tocviewlink" data-pltdoc="x">Blocking the Current Thread</a></td></tr><tr><td align="right">10.4&nbsp;</td><td><a href="#%28part._threadtime%29" class="tocviewlink" data-pltdoc="x">Threads in Embedded Racket with Event Loops</a></td></tr><tr><td align="right">10.5&nbsp;</td><td><a href="#%28part._sleeping%29" class="tocviewlink" data-pltdoc="x">Sleeping by Embedded Racket</a></td></tr><tr><td align="right">10.6&nbsp;</td><td><a href="#%28part._.Thread_.Functions%29" class="tocviewlink" data-pltdoc="x">Thread Functions</a></td></tr></table></div></div></div><div class="tocsub"><div class="tocsubtitle">On this page:</div><table class="tocsublist" cellspacing="0"><tr><td><span class="tocsublinknumber">10.1<tt>&nbsp;</tt></span><a href="#%28part._.Integration_with_.Threads%29" class="tocsubseclink" data-pltdoc="x">Integration with Threads</a></td></tr><tr><td><span class="tocsublinknumber">10.2<tt>&nbsp;</tt></span><a href="#%28part._usefuel%29" class="tocsubseclink" data-pltdoc="x">Allowing Thread Switches</a></td></tr><tr><td><span class="tocsublinknumber">10.3<tt>&nbsp;</tt></span><a href="#%28part._threadblock%29" class="tocsubseclink" data-pltdoc="x">Blocking the Current Thread</a></td></tr><tr><td><span class="tocsublinknumber">10.4<tt>&nbsp;</tt></span><a href="#%28part._threadtime%29" class="tocsubseclink" data-pltdoc="x">Threads in Embedded Racket with Event Loops</a></td></tr><tr><td><span class="tocsublinknumber">10.4.1<tt>&nbsp;</tt></span><a href="#%28part._blockednonmainel%29" class="tocsubseclink" data-pltdoc="x">Callbacks for Blocked Threads</a></td></tr><tr><td><span class="tocsublinknumber">10.5<tt>&nbsp;</tt></span><a href="#%28part._sleeping%29" class="tocsubseclink" data-pltdoc="x">Sleeping by Embedded Racket</a></td></tr><tr><td><span class="tocsublinknumber">10.6<tt>&nbsp;</tt></span><a href="#%28part._.Thread_.Functions%29" class="tocsubseclink" data-pltdoc="x">Thread Functions</a></td></tr></table></div></div><div class="maincolumn"><div class="main"><div class="navsettop"><span class="navleft"><form class="searchform"><input class="searchbox" style="color: #888;" type="text" value="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, &quot;6.1&quot;, &quot;../&quot;);" onfocus="this.style.color=&quot;black&quot;; this.style.textAlign=&quot;left&quot;; if (this.value == &quot;...search manuals...&quot;) this.value=&quot;&quot;;" onblur="if (this.value.match(/^ *$/)) { this.style.color=&quot;#888&quot;; this.style.textAlign=&quot;center&quot;; this.value=&quot;...search manuals...&quot;; }"/></form>&nbsp;&nbsp;<a href="../index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot(&quot;6.1&quot;);">top</a></span><span class="navright">&nbsp;&nbsp;<a href="exceptions.html" title="backward to &quot;9 Exceptions and Escape Continuations&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;Inside: Racket C API&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="config.html" title="forward to &quot;11 Parameterizations&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div><h3 x-source-module="(lib &quot;scribblings/inside/inside.scrbl&quot;)" x-part-tag="&quot;threads&quot;">10<tt>&nbsp;</tt><a name="(part._threads)"></a>Threads</h3><p>The initializer function <a href="Evaluation.html#%28cpp._scheme_basic_env%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_basic_env</span></a> creates the main
Racket thread; all other threads are created through calls to
<a href="#%28cpp._scheme_thread%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_thread</span></a>.</p><p>Information about each internal Racket thread is kept in a
<span class="stt">Scheme_Thread</span> structure. A pointer to the current thread&rsquo;s
structure is available as <span class="stt">scheme_current_thread</span>.  A
<span class="stt">Scheme_Thread</span> structure includes the following fields:</p><ul><li><p><span class="stt">error_buf</span> &#8212;<wbr></wbr> the <span class="stt">mz_jmp_buf</span> value used to escape
from errors. The <span class="stt">error_buf</span> value of the current thread is
available as <span class="stt">scheme_error_buf</span>.</p></li><li><p><span class="stt">cjs.jumping_to_continuation</span> &#8212;<wbr></wbr> a flag that
distinguishes escaping-continuation invocations from error
escapes. The <span class="stt">cjs.jumping_to_continuation</span> value of the current
thread is available as <span class="stt">scheme_jumping_to_continuation</span>.</p></li><li><p><span class="stt">init_config</span> &#8212;<wbr></wbr>
the thread&rsquo;s initial parameterization. See also <a href="config.html" data-pltdoc="x">Parameterizations</a>.</p></li><li><p><span class="stt">cell_values</span> &#8212;<wbr></wbr> The thread&rsquo;s values for thread cells
(see also <a href="config.html" data-pltdoc="x">Parameterizations</a>).</p></li><li><p><span class="stt">next</span> &#8212;<wbr></wbr> The next thread in the linked list of threads;
this is <span class="stt">NULL</span> for the main thread.</p></li></ul><p>The list of all scheduled threads is kept in a linked list;
<span class="stt">scheme_first_thread</span> points to the first thread in the list.
The last thread in the list is always the main thread.</p><h4 x-source-module="(lib &quot;scribblings/inside/inside.scrbl&quot;)" x-part-tag="&quot;Integration_with_Threads&quot;">10.1<tt>&nbsp;</tt><a name="(part._.Integration_with_.Threads)"></a>Integration with Threads</h4><p>Racket&rsquo;s threads can break external C code under two circumstances:</p><ul><li><p><span style="font-style: italic">Pointers to stack-based values can be communicated
between threads.</span>  For example, if thread A stores a pointer to a
stack-based variable in a global variable, if thread B uses the
pointer in the global variable, it may point to data that is not
currently on the stack.</p></li><li><p><span style="font-style: italic">C functions that can invoke Racket (and also be invoked
by Racket) depend on strict function-call nesting.</span> For example,
suppose a function F uses an internal stack, pushing items on to the
stack on entry and popping the same items on exit. Suppose also that
F invokes Racket to evaluate an expression.  If the evaluation of
this expression invokes F again in a new thread, but then returns to
the first thread before completing the second F, then F&rsquo;s internal
stack will be corrupted.</p></li></ul><p>If either of these circumstances occurs, Racket will probably crash.</p><h4 x-source-module="(lib &quot;scribblings/inside/inside.scrbl&quot;)" x-part-tag="&quot;usefuel&quot;">10.2<tt>&nbsp;</tt><a name="(part._usefuel)"></a>Allowing Thread Switches</h4><p>C code that performs substantial or unbounded work should occasionally
call <span class="stt">SCHEME_USE_FUEL</span>&#8212;<wbr></wbr>actually a macro&#8212;<wbr></wbr>which allows Racket
to swap in another Racket thread to run, and to check for breaks on
the current thread.  In particular, if breaks are enabled, then
<span class="stt">SCHEME_USE_FUEL</span> may trigger an exception.</p><p>The macro consumes an integer argument. On most platforms, where
thread scheduling is based on timer interrupts, the argument is
ignored. On some platforms, however, the integer represents the amount
of &ldquo;fuel&rdquo; that has been consumed since the last call to
<span class="stt">SCHEME_USE_FUEL</span>. For example, the implementation of
<span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=vectors.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._vector-%7E3elist%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">vector-&gt;list</a></span> consumes a unit of fuel for each created cons
cell:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">Scheme_Object *scheme_vector_to_list(Scheme_Object *vec)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">{</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">int i;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">Scheme_Object *pair = scheme_null;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">i = SCHEME_VEC_SIZE(vec);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">for (; i--; ) {</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">SCHEME_USE_FUEL(1);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">pair = scheme_make_pair(SCHEME_VEC_ELS(vec)[i], pair);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">return pair;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr></table></p><p>The <span class="stt">SCHEME_USE_FUEL</span> macro expands to a C block, not an
expression.</p><h4 x-source-module="(lib &quot;scribblings/inside/inside.scrbl&quot;)" x-part-tag="&quot;threadblock&quot;">10.3<tt>&nbsp;</tt><a name="(part._threadblock)"></a>Blocking the Current Thread</h4><p>Embedding or extension code sometimes needs to block, but blocking
should allow other Racket threads to execute. To allow other threads
to run, block using <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a>.  This procedure takes
two functions: a polling function that tests whether the blocking
operation can be completed, and a prepare-to-sleep function that sets
bits in <span class="stt">fd_set</span>s when Racket decides to sleep (because all Racket
threads are blocked). On Windows, an &ldquo;<span class="stt">fd_set</span>&rdquo; can also
accommodate OS-level semaphores or other handles via
<a href="#%28cpp._scheme_add_fd_handle%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_fd_handle</span></a>.</p><p>Since the functions passed to <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a> are called by
the Racket thread scheduler, they must never raise exceptions, call
<a href="Evaluation.html#%28cpp._scheme_apply%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_apply</span></a>, or trigger the evaluation of Racket code in any
way. The <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a> function itself may call the current
exception handler, however, in reaction to a break (if breaks are
enabled).</p><p>When a blocking operation is associated with an object, then the
object might make sense as an argument to <a name="(idx._(gentag._351._(lib._scribblings/inside/inside..scrbl)))"></a><span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=sync.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._sync%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">sync</a></span>. To
extend the set of objects accepted by <span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=sync.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._sync%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">sync</a></span>, either register
polling and sleeping functions with <a href="#%28cpp._scheme_add_evt%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_evt</span></a>, or register
a semaphore accessor with <a href="#%28cpp._scheme_add_evt_through_sema%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_evt_through_sema</span></a>.</p><p>The <a href="#%28cpp._scheme_signal_received%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_signal_received</span></a> function can be called to wake up
Racket when it is sleeping. In particular, calling
<a href="#%28cpp._scheme_signal_received%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_signal_received</span></a> ensures that Racket will poll all
blocking synchronizations soon afterward. Furthermore,
<a href="#%28cpp._scheme_signal_received%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_signal_received</span></a> can be called from any OS-level thread.
Thus, when no adequate prepare-to-sleep function can be implemented
for <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a> in terms of file descriptors or Windows
handles, calling <a href="#%28cpp._scheme_signal_received%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_signal_received</span></a> when the poll result
changes will ensure that a poll is issued.</p><h4 x-source-module="(lib &quot;scribblings/inside/inside.scrbl&quot;)" x-part-tag="&quot;threadtime&quot;">10.4<tt>&nbsp;</tt><a name="(part._threadtime)"></a>Threads in Embedded Racket with Event Loops</h4><p>When Racket is embedded in an application with an event-based model
(i.e., the execution of Racket code in the main thread is repeatedly
triggered by external events until the application exits) special
hooks must be set to ensure that non-main threads execute
correctly. For example, during the execution in the main thread, a new
thread may be created; the new thread may still be running when the
main thread returns to the event loop, and it may be arbitrarily long
before the main thread continues from the event loop. Under such
circumstances, the embedding program must explicitly allow Racket to
execute the non-main threads; this can be done by periodically calling
the function <a href="#%28cpp._scheme_check_threads%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_check_threads</span></a>.</p><p>Thread-checking only needs to be performed when non-main threads exist
(or when there are active callback triggers). The embedding
application can set the global function pointer
<span class="stt">scheme_notify_multithread</span> to a function that takes an integer
parameter and returns <span class="stt">void</span>.  This function is be called with 1
when thread-checking becomes necessary, and then with 0 when thread
checking is no longer necessary. An embedding program can use this
information to prevent unnecessary <a href="#%28cpp._scheme_check_threads%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_check_threads</span></a> polling.</p><p>The below code illustrates how GRacket formerly set up
<a href="#%28cpp._scheme_check_threads%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_check_threads</span></a> polling using the wxWindows <span class="stt">wxTimer</span>
class. (Any regular event-loop-based callback is appropriate.) The
<span class="stt">scheme_notify_multithread</span> pointer is set to
<span class="stt">MrEdInstallThreadTimer</span>. (GRacket no longer work this way, however.)</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">class MrEdThreadTimer : public wxTimer</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">{</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;</span><span class="stt">public:</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">void Notify(void); /* callback when timer expires */</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">};</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">static int threads_go;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">static MrEdThreadTimer *theThreadTimer;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">#define THREAD_WAIT_TIME 40</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">void MrEdThreadTimer::Notify()</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">{</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">if (threads_go)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">Start(THREAD_WAIT_TIME, TRUE);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">scheme_check_threads();</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">static void MrEdInstallThreadTimer(int on)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">{</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">if (!theThreadTimer)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">theThreadTimer = new MrEdThreadTimer;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">if (on)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">theThreadTimer-&gt;Start(THREAD_WAIT_TIME, TRUE);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">else</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">theThreadTimer-&gt;Stop();</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">threads_go = on;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">if (on)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">do_this_time = 1;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr></table></p><p>An alternate architecture, which GRacket now uses, is to send the main
thread into a loop, which blocks until an event is ready to handle.
Racket automatically takes care of running all threads, and it does so
efficiently because the main thread blocks on a file descriptor, as
explained in <a href="#%28part._threadblock%29" data-pltdoc="x">Blocking the Current Thread</a>.</p><h5 x-source-module="(lib &quot;scribblings/inside/inside.scrbl&quot;)" x-part-tag="&quot;blockednonmainel&quot;">10.4.1<tt>&nbsp;</tt><a name="(part._blockednonmainel)"></a>Callbacks for Blocked Threads</h5><p>Racket threads are sometimes blocked on file descriptors, such as an
input file or the X event socket. Blocked non-main threads do not
block the main thread, and therefore do not affect the event loop, so
<a href="#%28cpp._scheme_check_threads%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_check_threads</span></a> is sufficient to implement this case
correctly. However, it is wasteful to poll these descriptors with
<a href="#%28cpp._scheme_check_threads%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_check_threads</span></a> when nothing else is happening in the
application and when a lower-level poll on the file descriptors can be
installed. If the global function pointer
<span class="stt">scheme_wakeup_on_input</span> is set, then this case is handled more
efficiently by turning off thread checking and issuing a &ldquo;wakeup&rdquo;
request on the blocking file descriptors through
<span class="stt">scheme_wakeup_on_input</span>.</p><p>A <span class="stt">scheme_wakeup_on_input</span> procedure takes a pointer to an array
of three <span class="stt">fd_set</span>s (use <span class="stt">MZ_FD_SET</span> instead of <span class="stt">FD_SET</span>, etc.)
and returns <span class="stt">void</span>. The <span class="stt">scheme_wakeup_on_input</span>
function does not sleep immediately; it just
sets up callbacks on the specified file descriptors.  When input is
ready on any of those file descriptors, the callbacks are removed and
<a href="#%28cpp._scheme_wake_up%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_wake_up</span></a> is called.</p><p>For example, the X Windows version of GRacket formerly set
<span class="stt">scheme_wakeup_on_input</span> to this <span class="stt">MrEdNeedWakeup</span>:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">static XtInputId *scheme_cb_ids = NULL;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">static int num_cbs;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">static void MrEdNeedWakeup(void *fds)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">{</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">int limit, count, i, p;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">fd_set *rd, *wr, *ex;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">rd = (fd_set *)fds;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">wr = ((fd_set *)fds) + 1;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">ex = ((fd_set *)fds) + 2;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">limit = getdtablesize();</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">/* See if we need to do any work, really: */</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">count = 0;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">for (i = 0; i &lt; limit; i++) {</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">if (MZ_FD_ISSET(i, rd))</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">count++;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">if (MZ_FD_ISSET(i, wr))</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">count++;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">if (MZ_FD_ISSET(i, ex))</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">count++;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">if (!count)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">return;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">/* Remove old callbacks: */</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">if (scheme_cb_ids)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">for (i = 0; i &lt; num_cbs; i++)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">notify_set_input_func((Notify_client)NULL, (Notify_func)NULL,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">scheme_cb_ids[i]);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">num_cbs = count;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">scheme_cb_ids = new int[num_cbs];</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">/* Install callbacks */</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">p = 0;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">for (i = 0; i &lt; limit; i++) {</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">if (MZ_FD_ISSET(i, rd))</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">scheme_cb_ids[p++] = XtAppAddInput(wxAPP_CONTEXT, i,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(XtPointer *)XtInputReadMask,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(XtInputCallbackProc)MrEdWakeUp, NULL);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">if (MZ_FD_ISSET(i, wr))</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">scheme_cb_ids[p++] = XtAppAddInput(wxAPP_CONTEXT, i,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(XtPointer *)XtInputWriteMask,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(XtInputCallbackProc)MrEdWakeUp, NULL);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">if (MZ_FD_ISSET(i, ex))</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">scheme_cb_ids[p++] = XtAppAddInput(wxAPP_CONTEXT, i,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(XtPointer *)XtInputExceptMask,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">(XtInputCallbackProc)MrEdWakeUp,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">NULL);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">/* callback function when input/exception is detected: */</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">Bool MrEdWakeUp(XtPointer, int *, XtInputId *)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">{</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">int i;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">if (scheme_cb_ids) {</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">/* Remove all callbacks: */</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">for (i = 0; i &lt; num_cbs; i++)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">XtRemoveInput(scheme_cb_ids[i]);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">scheme_cb_ids = NULL;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">/* ``wake up'' */</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">scheme_wake_up();</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">return FALSE;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr></table></p><h4 x-source-module="(lib &quot;scribblings/inside/inside.scrbl&quot;)" x-part-tag="&quot;sleeping&quot;">10.5<tt>&nbsp;</tt><a name="(part._sleeping)"></a>Sleeping by Embedded Racket</h4><p>When all Racket threads are blocked, Racket must &ldquo;sleep&rdquo; for a
certain number of seconds or until external input appears on some file
descriptor. Generally, sleeping should block the main event loop of
the entire application. However, the way in which sleeping is
performed may depend on the embedding application. The global function
pointer <span class="stt">scheme_sleep</span> can be set by an embedding application to
implement a blocking sleep, although Racket implements this function
for you.</p><p>A <span class="stt">scheme_sleep</span> function takes two arguments: a <span class="stt">float</span> and a
<span class="stt">void*</span>. The latter is really points to an array of three
&ldquo;<span class="stt">fd_set</span>&rdquo; records (one for read, one for write, and one for
exceptions); these records are described further below. If the
<span class="stt">float</span> argument is non-zero, then the <span class="stt">scheme_sleep</span> function
blocks for the specified number of seconds, at most. The
<span class="stt">scheme_sleep</span> function should block until there is input one of
the file descriptors specified in the &ldquo;<span class="stt">fd_set</span>,&rdquo; indefinitely
if the <span class="stt">float</span> argument is zero.</p><p>The second argument to <span class="stt">scheme_sleep</span> is conceptually an array of
three <span class="stt">fd_set</span> records, but always use <a href="#%28cpp._scheme_get_fdset%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_get_fdset</span></a> to
get anything other than the zeroth element of this array, and
manipulate each &ldquo;<span class="stt">fd_set</span>&rdquo; with <span class="stt">MZ_FD_SET</span>,
<span class="stt">MZ_FD_CLR</span>, etc<span class="Sendabbrev">.</span> instead of <span class="stt">FD_SET</span>, <span class="stt">FD_CLR</span>, etc.</p><p>The following function <span class="stt">mzsleep</span> is an appropriate
<span class="stt">scheme_sleep</span> function for most any Unix or Windows application.
(This is approximately the built-in sleep used by Racket.)</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">void mzsleep(float v, void *fds)</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">{</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">if (v) {</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">sleep(v);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">} else {</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">int limit;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">fd_set *rd, *wr, *ex;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"># ifdef WIN32</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">limit = 0;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"># else</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">limit = getdtablesize();</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"># endif</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">rd = (fd_set *)fds;</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">wr = (fd_set *)scheme_get_fdset(fds, 1);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">ex = (fd_set *)scheme_get_fdset(fds, 2);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">select(limit, rd, wr, ex, NULL);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">}</span></p></td></tr></table></p><h4 x-source-module="(lib &quot;scribblings/inside/inside.scrbl&quot;)" x-part-tag="&quot;Thread_Functions&quot;">10.6<tt>&nbsp;</tt><a name="(part._.Thread_.Functions)"></a>Thread Functions</h4><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">Scheme_Object*</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_thread)"></a><a name="(idx._(gentag._352._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_thread%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_thread</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">thunk</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Creates a new thread, just like <span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=threads.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._thread%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">thread</a></span>.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td colspan="3"><p><span class="stt">Scheme_Object*</span></p></td></tr><tr><td><p><a name="(cpp._scheme_thread_w_details)"></a><a name="(idx._(gentag._353._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_thread_w_details%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_thread_w_details</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">thunk</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Config*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">config</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Thread_Cell_Table*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">cells</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Custodian*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">cust</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">suspend_to_kill</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Like <a href="#%28cpp._scheme_thread%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_thread</span></a>, except that the created thread belongs to
<span style="font-style: italic">cust</span> instead of the current custodian, it uses the given
<span style="font-style: italic">config</span> for its initial configuration, it uses <span style="font-style: italic">cells</span> for
its thread-cell table, and if <span style="font-style: italic">suspend_to_kill</span> is non-zero, then
the thread is merely suspended when it would otherwise be killed
(through either <span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=threads.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._kill-thread%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">kill-thread</a></span> or
<span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=custodians.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._custodian-shutdown-all%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">custodian-shutdown-all</a></span>).</div></p><p>The <span style="font-style: italic">config</span> argument is typically obtained through
<span class="stt">scheme_current_config</span> or <a href="config.html#%28cpp._scheme_extend_config%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_extend_config</span></a>. A
<span style="font-style: italic">config</span> is immutable, so different threads can safely use the
same value. The <span style="font-style: italic">cells</span> argument should be obtained from
<a href="config.html#%28cpp._scheme_inherit_cells%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_inherit_cells</span></a>; it is mutable, and a particular cell table
should be used by only one thread.</p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">Scheme_Object*</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_make_sema)"></a><a name="(idx._(gentag._354._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_make_sema%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_make_sema</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">intptr_t</span><span class="hspace">&nbsp;</span><span style="font-style: italic">v</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Creates a new semaphore.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_post_sema)"></a><a name="(idx._(gentag._355._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_post_sema%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_post_sema</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">sema</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Posts to <span style="font-style: italic">sema</span>.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">int</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_wait_sema)"></a><a name="(idx._(gentag._356._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_wait_sema%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_wait_sema</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">sema</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">try</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Waits on <span style="font-style: italic">sema</span>. If <span style="font-style: italic">try</span> is not 0, the wait can fail and 0 is
returned for failure, otherwise 1 is returned.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_thread_block)"></a><a name="(idx._(gentag._357._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_thread_block%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_thread_block</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">float</span><span class="hspace">&nbsp;</span><span style="font-style: italic">sleep_time</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Allows the current thread to be swapped out in favor of other
threads. If <span style="font-style: italic">sleep_time</span> positive, then the current thread will
sleep for at least <span style="font-style: italic">sleep_time</span> seconds.</div></p><p>After calling this function, a program should almost always call
<a href="#%28cpp._scheme_making_progress%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_making_progress</span></a> next. The exception is when
<a href="#%28cpp._scheme_thread_block%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_thread_block</span></a> is called in a polling loop that performs no
work that affects the progress of other threads. In that case,
<a href="#%28cpp._scheme_making_progress%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_making_progress</span></a> should be called immediately after
exiting the loop.</p><p>See also <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a>, and see also the
<span class="stt">SCHEME_USE_FUEL</span> macro in <a href="#%28part._usefuel%29" data-pltdoc="x">Allowing Thread Switches</a>.</p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_thread_block_enable_break)"></a><a name="(idx._(gentag._358._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_thread_block_enable_break%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_thread_block_enable_break</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">float</span><span class="hspace">&nbsp;</span><span style="font-style: italic">sleep_time</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">break_on</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Like <a href="#%28cpp._scheme_thread_block%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_thread_block</span></a>, but breaks are enabled while blocking if
 <span style="font-style: italic">break_on</span> is true.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_swap_thread)"></a><a name="(idx._(gentag._359._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_swap_thread%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_swap_thread</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Thread*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">thread</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Swaps out the current thread in favor of <span style="font-style: italic">thread</span>.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_break_thread)"></a><a name="(idx._(gentag._360._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_break_thread%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_break_thread</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Thread*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">thread</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Sends a break signal to the given thread.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">int</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_break_waiting)"></a><a name="(idx._(gentag._361._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_break_waiting%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_break_waiting</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Thread*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">thread</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Returns <span class="stt">1</span> if a break from <span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=threads.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._break-thread%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">break-thread</a></span> or <a href="#%28cpp._scheme_break_thread%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_break_thread</span></a>
 has occurred in the specified thread but has not yet been handled.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">int</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_block_until)"></a><a name="(idx._(gentag._362._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Ready_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">f</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Needs_Wakeup_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">fdf</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">data</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">float</span><span class="hspace">&nbsp;</span><span style="font-style: italic">sleep</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">The <span class="stt">Scheme_Ready_Fun</span> and <span class="stt">Scheme_Needs_Wakeup_Fun</span>
 types are defined as follows:</div></p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">typedef int (*Scheme_Ready_Fun)(Scheme_Object *data);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">typedef void (*Scheme_Needs_Wakeup_Fun)(Scheme_Object *data,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">void *fds);</span></p></td></tr></table></p><p>Blocks the current thread until <span style="font-style: italic">f</span> with <span style="font-style: italic">data</span> returns a true
 value.  The <span style="font-style: italic">f</span> function is called periodically&#8212;<wbr></wbr>at least once
 per potential swap-in of the blocked thread&#8212;<wbr></wbr>and it may be called
 multiple times even after it returns a true value. If <span style="font-style: italic">f</span>
 with <span style="font-style: italic">data</span> ever returns a true value, it must continue to return
 a true value until <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a> returns. The argument
 to <span style="font-style: italic">f</span> is the same <span style="font-style: italic">data</span> as provided
 to <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a>, and <span style="font-style: italic">data</span> is ignored
 otherwise. (The <span style="font-style: italic">data</span> argument is not actually required to be
 a <span class="stt">Scheme_Object*</span> value, because it is only used by <span style="font-style: italic">f</span>
 and <span style="font-style: italic">fdf</span>.)</p><p>If Racket decides to sleep, then the <span style="font-style: italic">fdf</span> function is called to
 sets bits in <span style="font-style: italic">fds</span>, conceptually an array of three
 <span class="stt">fd_set</span>s: one or reading, one for writing, and one for
 exceptions. Use <a href="#%28cpp._scheme_get_fdset%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_get_fdset</span></a> to get elements of this
 array, and manipulate an &ldquo;<span class="stt">fd_set</span>&rdquo; with <span class="stt">MZ_FD_SET</span>
 instead of <span class="stt">FD_SET</span>, etc. On Windows, an &ldquo;<span class="stt">fd_set</span>&rdquo; can
 also accommodate OS-level semaphores or other handles via
 <a href="#%28cpp._scheme_add_fd_handle%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_fd_handle</span></a>.</p><p>The <span style="font-style: italic">fdf</span> argument can be <span class="stt">NULL</span>, which implies that the thread
 becomes unblocked (i.e., <span style="font-style: italic">ready</span> changes its result to true) only
 through Racket actions, and never through external processes (e.g.,
 through a socket or OS-level semaphore)&#8212;<wbr></wbr>with the exception that
 <a href="#%28cpp._scheme_signal_received%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_signal_received</span></a> may be called to indicate an external
 change.</p><p>If <span style="font-style: italic">sleep</span> is a positive number, then <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a>
 polls <span style="font-style: italic">f</span> at least every <span style="font-style: italic">sleep</span> seconds, but
 <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a> does not return until <span style="font-style: italic">f</span> returns a
 true value. The call to <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a> can return before
 <span style="font-style: italic">sleep</span> seconds if <span style="font-style: italic">f</span> returns a true value.</p><p>The return value from <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a> is the return value
 of its most recent call to <span style="font-style: italic">f</span>, which enables <span style="font-style: italic">f</span> to return
 some information to the <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a> caller.</p><p>See <a href="#%28part._threadblock%29" data-pltdoc="x">Blocking the Current Thread</a> for information about restrictions on the
 <span style="font-style: italic">f</span> and <span style="font-style: italic">fdf</span> functions.</p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">int</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_block_until_enable_break)"></a><a name="(idx._(gentag._363._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_block_until_enable_break%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until_enable_break</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Ready_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">f</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Needs_Wakeup_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">fdf</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">data</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">float</span><span class="hspace">&nbsp;</span><span style="font-style: italic">sleep</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">break_on</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Like <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a>, but breaks are enabled while blocking
 if <span style="font-style: italic">break_on</span> is true.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">int</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_block_until_unless)"></a><a name="(idx._(gentag._364._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_block_until_unless%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until_unless</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Ready_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">f</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Needs_Wakeup_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">fdf</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">data</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">float</span><span class="hspace">&nbsp;</span><span style="font-style: italic">sleep</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">unless_evt</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">break_on</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Like <a href="#%28cpp._scheme_block_until_enable_break%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until_enable_break</span></a>, but the function
 returns if <span style="font-style: italic">unless_evt</span> becomes ready, where <span style="font-style: italic">unless_evt</span>
 is a port progress event implemented by
 <span class="stt">scheme_progress_evt_via_get</span>. See
 <a href="Ports_and_the_Filesystem.html#%28cpp._scheme_make_input_port%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_make_input_port</span></a> for more information.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_signal_received)"></a><a name="(idx._(gentag._365._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_signal_received%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_signal_received</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Indicates that an external event may have caused the result of a
synchronization poll to have a different result. Unlike most other
Racket functions, this one can be called from any OS-level thread, and
it wakes up if the Racket thread if it is sleeping.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_check_threads)"></a><a name="(idx._(gentag._366._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_check_threads%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_check_threads</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">This function is periodically called by the embedding program to give
background processes time to execute. See <a href="#%28part._threadtime%29" data-pltdoc="x">Threads in Embedded Racket with Event Loops</a>
for more information.</div></p><p>As long as some threads are ready, this functions returns only after
one thread quantum, at least.</p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_wake_up)"></a><a name="(idx._(gentag._367._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_wake_up%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_wake_up</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">This function is called by the embedding program
when there is input on an external file descriptor. See
<a href="#%28part._sleeping%29" data-pltdoc="x">Sleeping by Embedded Racket</a> for more information.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void*</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_get_fdset)"></a><a name="(idx._(gentag._368._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_get_fdset%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_get_fdset</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">void*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">fds</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">pos</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Extracts an &ldquo;<span class="stt">fd_set</span>&rdquo; from an array passed to
 <span class="stt">scheme_sleep</span>, a callback for <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a>, or an
 input port callback for <a href="Ports_and_the_Filesystem.html#%28cpp._scheme_make_input_port%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_make_input_port</span></a>.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_add_fd_handle)"></a><a name="(idx._(gentag._369._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_add_fd_handle%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_fd_handle</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">void*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">h</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">void*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">fds</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">repost</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Adds an OS-level semaphore (Windows) or other waitable handle
 (Windows) to the &ldquo;<span class="stt">fd_set</span>&rdquo; <span style="font-style: italic">fds</span>. When Racket performs
 a &ldquo;<span class="stt">select</span>&rdquo; to sleep on <span style="font-style: italic">fds</span>, it also waits on the given
 semaphore or handle. This feature makes it possible for Racket to
 sleep until it is awakened by an external process.</div></p><p>Racket does not attempt to deallocate the given semaphore or handle,
 and the &ldquo;<span class="stt">select</span>&rdquo; call using <span style="font-style: italic">fds</span> may be unblocked due to
 some other file descriptor or handle in <span style="font-style: italic">fds</span>. If <span style="font-style: italic">repost</span> is
 a true value, then <span style="font-style: italic">h</span> must be an OS-level semaphore, and if the
 &ldquo;<span class="stt">select</span>&rdquo; unblocks due to a post on <span style="font-style: italic">h</span>, then <span style="font-style: italic">h</span> is
 reposted; this allows clients to treat <span style="font-style: italic">fds</span>-installed semaphores
 uniformly, whether or not a post on the semaphore was consumed by
 &ldquo;<span class="stt">select</span>&rdquo;.</p><p>The <a href="#%28cpp._scheme_add_fd_handle%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_fd_handle</span></a> function is useful for implementing
 the second procedure passed to <span class="stt">scheme_wait_until</span>, or for
 implementing a custom input port.</p><p>On Unix and Mac OS X, this function has no effect.</p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_add_fd_eventmask)"></a><a name="(idx._(gentag._370._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_add_fd_eventmask%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_fd_eventmask</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">void*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">fds</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">mask</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Adds an OS-level event type (Windows) to the set of types in the
 &ldquo;<span class="stt">fd_set</span>&rdquo; <span style="font-style: italic">fds</span>. When Racket performs a
 &ldquo;<span class="stt">select</span>&rdquo; to sleep on <span style="font-style: italic">fds</span>, it also waits on events of
 them specified type. This feature makes it possible for Racket to
 sleep until it is awakened by an external process.</div></p><p>The event mask is only used when some handle is installed with
 <a href="#%28cpp._scheme_add_fd_handle%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_fd_handle</span></a>. This awkward restriction may force you
 to create a dummy semaphore that is never posted.</p><p>On Unix, and Mac OS X, this function has no effect.</p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_add_evt)"></a><a name="(idx._(gentag._371._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_add_evt%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_evt</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Type</span><span class="hspace">&nbsp;</span><span style="font-style: italic">type</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Ready_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">ready</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Needs_Wakeup_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">wakeup</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Wait_Filter_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">filter</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">can_redirect</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">The argument types are defined as follows:</div></p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">typedef int (*Scheme_Ready_Fun)(Scheme_Object *data);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">typedef void (*Scheme_Needs_Wakeup_Fun)(Scheme_Object *data,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">void *fds);</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">typedef int (*Scheme_Wait_Filter_Fun)(Scheme_Object *data);</span></p></td></tr></table></p><p>Extends the set of waitable objects for <span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=sync.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._sync%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">sync</a></span>
 to those with the type tag <span style="font-style: italic">type</span>. If <span style="font-style: italic">filter</span> is
 non-<span class="stt">NULL</span>, it constrains the new waitable set to those objects
 for which <span style="font-style: italic">filter</span> returns a non-zero value.</p><p>The <span style="font-style: italic">ready</span> and <span style="font-style: italic">wakeup</span> functions are used in the same way
 was the arguments to <a href="#%28cpp._scheme_block_until%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_block_until</span></a>.</p><p>The <span style="font-style: italic">can_redirect</span> argument should be <span class="stt">0</span>.</p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_add_evt_through_sema)"></a><a name="(idx._(gentag._372._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_add_evt_through_sema%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_evt_through_sema</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Type</span><span class="hspace">&nbsp;</span><span style="font-style: italic">type</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Wait_Sema_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">getsema</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Wait_Filter_Fun</span><span class="hspace">&nbsp;</span><span style="font-style: italic">filter</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Like <a href="#%28cpp._scheme_add_evt%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_evt</span></a>, but for objects where waiting is based
 on a semaphore. Instead of <span style="font-style: italic">ready</span> and <span style="font-style: italic">wakeup</span> functions,
 the <span style="font-style: italic">getsema</span> function extracts a semaphore for a given object:</div></p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">typedef</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">Scheme_Object *(*Scheme_Wait_Sema_Fun)(Scheme_Object *data,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">int *repost);</span></p></td></tr></table></p><p>If a successful wait should leave the semaphore waited, then
 <span style="font-style: italic">getsema</span> should set <span style="font-style: italic">*repost</span> to <span class="stt">0</span>. Otherwise, the
 given semaphore will be re-posted after a successful wait. A
 <span style="font-style: italic">getsema</span> function should almost always set <span style="font-style: italic">*repost</span> to
 <span class="stt">1</span>.</p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_making_progress)"></a><a name="(idx._(gentag._373._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_making_progress%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_making_progress</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Notifies the scheduler that the current thread is not simply calling
 <a href="#%28cpp._scheme_thread_block%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_thread_block</span></a> in a loop, but that it is actually
 making progress.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">int</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_tls_allocate)"></a><a name="(idx._(gentag._374._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_tls_allocate%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_tls_allocate</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Allocates a thread local storage index to be used with
 <a href="#%28cpp._scheme_tls_set%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_tls_set</span></a> and <a href="#%28cpp._scheme_tls_get%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_tls_get</span></a>.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_tls_set)"></a><a name="(idx._(gentag._375._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_tls_set%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_tls_set</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">index</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">void*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">v</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Stores a thread-specific value using an index allocated with
<a href="#%28cpp._scheme_tls_allocate%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_tls_allocate</span></a>.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void*</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_tls_get)"></a><a name="(idx._(gentag._376._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_tls_get%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_tls_get</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">index</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Retrieves a thread-specific value installed with <a href="#%28cpp._scheme_tls_set%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_tls_set</span></a>.
If no thread-specific value is available for the given index, <span class="stt">NULL</span> is
returned.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">Scheme_Object*</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_call_enable_break)"></a><a name="(idx._(gentag._377._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_call_enable_break%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_call_enable_break</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Prim*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">prim</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">argc</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object**</span><span class="hspace">&nbsp;</span><span style="font-style: italic">argv</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Calls <span style="font-style: italic">prim</span> with the given <span style="font-style: italic">argc</span> and <span style="font-style: italic">argv</span> with breaks
 enabled. The <span style="font-style: italic">prim</span> function can block, in which case it might be
 interrupted by a break. The <span style="font-style: italic">prim</span> function should not block,
 yield, or check for breaks after it succeeds, where &ldquo;succeeds&rdquo;
 depends on the operation. For example,
 <span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=tcp.html%23%2528def._%2528%2528lib._racket%252Ftcp..rkt%2529._tcp-accept%252Fenable-break%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">tcp-accept/enable-break</a></span> is implemented by wrapping this
 function around the implementation of <span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=tcp.html%23%2528def._%2528%2528lib._racket%252Ftcp..rkt%2529._tcp-accept%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">tcp-accept</a></span>; the
 <span class="RktSym"><a href="http://download.racket-lang.org/docs/6.1/html/local-redirect/index.html?doc=reference&amp;rel=tcp.html%23%2528def._%2528%2528lib._racket%252Ftcp..rkt%2529._tcp-accept%2529%2529&amp;version=6.1" class="RktValLink Sq" data-pltdoc="x">tcp-accept</a></span> implementation does not block or yield after it
 accepts a connection.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td colspan="3"><p><span class="stt">Scheme_Object*</span></p></td></tr><tr><td><p><a name="(cpp._scheme_make_thread_cell)"></a><a name="(idx._(gentag._378._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_make_thread_cell%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_make_thread_cell</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">def_val</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">int</span><span class="hspace">&nbsp;</span><span style="font-style: italic">preserved</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">cell</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Thread_Cell_Table*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">cells</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">cell</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Thread_Cell_Table*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">cells</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">v</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Prevents Racket thread swaps until <a href="#%28cpp._scheme_end_atomic%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_end_atomic</span></a> or
 <a href="#%28cpp._scheme_end_atomic_no_swap%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_end_atomic_no_swap</span></a> is called. Start-atomic and
 end-atomic pairs can be nested.</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_end_atomic)"></a><a name="(idx._(gentag._379._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_end_atomic%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_end_atomic</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Ends an atomic region with respect to Racket threads. The current
 thread may be swapped out immediately (i.e., the call to
 <a href="#%28cpp._scheme_end_atomic%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_end_atomic</span></a> is assumed to be a safe point for thread
 swaps).</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_end_atomic_no_swap)"></a><a name="(idx._(gentag._380._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_end_atomic_no_swap%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_end_atomic_no_swap</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Ends an atomic region with respect to Racket threads, and also
 prevents an immediate thread swap. (In other words, no Racket
 thread swaps will occur until a future safe point.)</div></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_add_swap_callback)"></a><a name="(idx._(gentag._381._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_add_swap_callback%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_swap_callback</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Closure_Func</span><span class="hspace">&nbsp;</span><span style="font-style: italic">f</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">data</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Registers a callback to be invoked just after a Racket thread is
swapped in. The <span style="font-style: italic">data</span> is provided back to <span style="font-style: italic">f</span> when it is
called, where <span class="stt">Closure_Func</span> is defined as follows:</div></p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;</span><span class="stt">typedef Scheme_Object *(*Scheme_Closure_Func)(Scheme_Object *);</span></p></td></tr></table></p><p><div class="SIntrapara"><table cellspacing="0" cellpadding="0" class="boxed"><tr><td><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">void</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><a name="(cpp._scheme_add_swap_out_callback)"></a><a name="(idx._(gentag._382._(lib._scribblings/inside/inside..scrbl)))"></a><a href="#%28cpp._scheme_add_swap_out_callback%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_swap_out_callback</span></a></p></td><td><p><span class="stt">(</span></p></td><td><p><span class="stt">Scheme_Closure_Func</span><span class="hspace">&nbsp;</span><span style="font-style: italic">f</span><span class="stt">,</span></p></td></tr><tr><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="hspace">&nbsp;</span></p></td><td><p><span class="stt">Scheme_Object*</span><span class="hspace">&nbsp;</span><span style="font-style: italic">data</span><span class="stt">)</span></p></td></tr></table></td></tr></table></div><div class="SIntrapara">Like <a href="#%28cpp._scheme_add_swap_callback%29" class="RktStxLink" data-pltdoc="x"><span class="stt">scheme_add_swap_callback</span></a>, but registers a callback to be
invoked just before a Racket thread is swapped out.</div></p><div class="navsetbottom"><span class="navleft"><form class="searchform"><input class="searchbox" style="color: #888;" type="text" value="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, &quot;6.1&quot;, &quot;../&quot;);" onfocus="this.style.color=&quot;black&quot;; this.style.textAlign=&quot;left&quot;; if (this.value == &quot;...search manuals...&quot;) this.value=&quot;&quot;;" onblur="if (this.value.match(/^ *$/)) { this.style.color=&quot;#888&quot;; this.style.textAlign=&quot;center&quot;; this.value=&quot;...search manuals...&quot;; }"/></form>&nbsp;&nbsp;<a href="../index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot(&quot;6.1&quot;);">top</a></span><span class="navright">&nbsp;&nbsp;<a href="exceptions.html" title="backward to &quot;9 Exceptions and Escape Continuations&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;Inside: Racket C API&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="config.html" title="forward to &quot;11 Parameterizations&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div></div></div><div id="contextindicator">&nbsp;</div></body></html>