aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-07-30 16:34:26 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-07-30 16:34:26 +0200
commit73813e8fd4104ba4cc56fc66180fb8408f289ba0 (patch)
tree41cda31201acaeeb8489011240ba4b02af05b2da /docs
parent6d9c547732506f0a8b006754bb9709699b05e6af (diff)
downloadlanes-73813e8fd4104ba4cc56fc66180fb8408f289ba0.tar.gz
lanes-73813e8fd4104ba4cc56fc66180fb8408f289ba0.tar.bz2
lanes-73813e8fd4104ba4cc56fc66180fb8408f289ba0.zip
Fix index.html
Diffstat (limited to 'docs')
-rw-r--r--docs/index.html166
1 files changed, 83 insertions, 83 deletions
diff --git a/docs/index.html b/docs/index.html
index 3afa7f0..79b33f1 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -97,11 +97,11 @@
97 <h3>Features:</h3> 97 <h3>Features:</h3>
98 98
99 <ul> 99 <ul>
100 <li>Lanes have separated data, by default. Shared data is possible with <a href="#lindas">Linda</a> objects.</li> 100 <li>Lanes have separated data, by default. Shared data is possible with <a href="#lindas">linda</a> objects.</li>
101 <li>Communications is separate of threads, using <a href="#lindas">Linda</a> objects.</li> 101 <li>Communications is separate of threads, using <a href="#lindas">linda</a> objects.</li>
102 <li>Data passing uses fast inter-state copies (no serialization required).</li> 102 <li>Data passing uses fast inter-state copies (no serialization required).</li>
103 <li>"Deep userdata" concept, for sharing userdata over multiple lanes.</li> 103 <li>"Deep userdata" concept, for sharing userdata over multiple lanes.</li>
104 <li>Millisecond level timers, integrated with the <a href="#lindas">Linda</a> system.</li> 104 <li>Millisecond level timers, integrated with the <a href="#lindas">linda</a> system.</li>
105 <li>Threads can be given priorities.</li> 105 <li>Threads can be given priorities.</li>
106 <li>Lanes are cancellable, with proper cleanup.</li> 106 <li>Lanes are cancellable, with proper cleanup.</li>
107 <li>No Lua-side application level locking - ever!</li> 107 <li>No Lua-side application level locking - ever!</li>
@@ -178,7 +178,7 @@
178<table border=1 bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> 178<table border=1 bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
179 <tr> 179 <tr>
180 <td> 180 <td>
181 <pre> extern void LANES_API luaopen_lanes_embedded(lua_State* L, lua_CFunction _luaopen_lanes);</pre> 181 <pre> LANES_API void luaopen_lanes_embedded(lua_State* L_, lua_CFunction luaopen_lanes_);</pre>
182 </td> 182 </td>
183 </tr> 183 </tr>
184</table> 184</table>
@@ -316,7 +316,7 @@
316 <tt>"libc"</tt>/<tt>"allocator"</tt> 316 <tt>"libc"</tt>/<tt>"allocator"</tt>
317 </td> 317 </td>
318 <td> 318 <td>
319 Controls which allocator is used for Lanes internal allocations (for <a href="#keepers">Keeper state</a>, <a href="#lindas">Linda</a> and lane management). 319 Controls which allocator is used for Lanes internal allocations (for <a href="#keepers">Keeper state</a>, <a href="#lindas">linda</a> and lane management).
320 If <tt>"libc"</tt>, Lanes uses <tt>realloc</tt> and <tt>free</tt>.<br /> 320 If <tt>"libc"</tt>, Lanes uses <tt>realloc</tt> and <tt>free</tt>.<br />
321 If <tt>"allocator"</tt>, Lanes uses whatever was obtained from the <tt>"allocator"</tt> setting.<br /> 321 If <tt>"allocator"</tt>, Lanes uses whatever was obtained from the <tt>"allocator"</tt> setting.<br />
322 This option is mostly useful for embedders that want control all memory allocations, but have issues when Lanes tries to use the Lua State allocator for internal purposes (especially with LuaJIT). 322 This option is mostly useful for embedders that want control all memory allocations, but have issues when Lanes tries to use the Lua State allocator for internal purposes (especially with LuaJIT).
@@ -342,9 +342,9 @@
342 </td> 342 </td>
343 <td>integer in [0,100]</td> 343 <td>integer in [0,100]</td>
344 <td> 344 <td>
345 Controls the number of "user" <a href="#keepers">Keeper state</a> used internally by <a href="#lindas">Linda</a>) objects to transfer data between lanes. Default is <tt>0</tt>.<br /> 345 Controls the number of "user" <a href="#keepers">Keeper state</a> used internally by <a href="#lindas">linda</a>) objects to transfer data between lanes. Default is <tt>0</tt>.<br />
346 Lanes always creates at least one keeper state (of group <tt>0</tt> for the internal timer <a href="#lindas">Linda</a>. If <tt>nb_user_keepers</tt> is <tt>0</tt>, the other lindas you create will share this keeper by necessity.<br /> 346 Lanes always creates at least one keeper state (of group <tt>0</tt> for the internal timer <a href="#lindas">linda</a>. If <tt>nb_user_keepers</tt> is <tt>0</tt>, the other lindas you create will share this keeper by necessity.<br />
347 If there is more than one <a href="#keepers">Keeper state</a> (in total), <a href="#lindas">Linda</a> creation must specify the group it belongs to. 347 If there is more than one <a href="#keepers">Keeper state</a> (in total), <a href="#lindas">linda</a> creation must specify the group it belongs to.
348 </td> 348 </td>
349 </tr> 349 </tr>
350 350
@@ -436,7 +436,7 @@
436</p> 436</p>
437 437
438<p> 438<p>
439 Once Lanes is configured, one should register with Lanes the modules exporting functions that will be transferred either during lane generation or through <a href="#lindas">Lindas</a>. 439 Once Lanes is configured, one should register with Lanes the modules exporting functions that will be transferred either during lane generation or through <a href="#lindas">lindas</a>.
440 <br /> 440 <br />
441 Use <tt>lanes.require()</tt> for this purpose. This will call the original <tt>require()</tt>, then add the result to the lookup databases. 441 Use <tt>lanes.require()</tt> for this purpose. This will call the original <tt>require()</tt>, then add the result to the lookup databases.
442 <br /> 442 <br />
@@ -469,7 +469,7 @@
469<p> 469<p>
470 An error will be raised if you attempt to do this from inside a lane, or on bad arguments (non-function, or too many arguments).<br /> 470 An error will be raised if you attempt to do this from inside a lane, or on bad arguments (non-function, or too many arguments).<br />
471 Only the last registered finalizer is kept. It can be cleared by passing <tt>nil</tt> or nothing.<br /> 471 Only the last registered finalizer is kept. It can be cleared by passing <tt>nil</tt> or nothing.<br />
472 The finalizer is called unprotected from inside <tt>__gc</tt> metamethod of Lane's Universe. Therefore, if your finalizer raises an error, Lua rules regarding errors in finalizers apply normally.<br /> 472 The finalizer is called unprotected from inside <tt>__gc</tt> metamethod of Lanes's Universe. Therefore, if your finalizer raises an error, Lua rules regarding errors in finalizers apply normally.<br />
473 The installed function is called after all free-running lanes got a chance to terminate (see <a href="#shutdown_timeout"><tt>shutdown_timeout</tt></a>), but before lindas become unusable.<br /> 473 The installed function is called after all free-running lanes got a chance to terminate (see <a href="#shutdown_timeout"><tt>shutdown_timeout</tt></a>), but before lindas become unusable.<br />
474 The finalizer receives a single argument, a <tt>bool</tt> indicating whether some Lanes are still running or not at that point. It is possible to inspect them with <a href="#tracking">tracking</a>.<br /> 474 The finalizer receives a single argument, a <tt>bool</tt> indicating whether some Lanes are still running or not at that point. It is possible to inspect them with <a href="#tracking">tracking</a>.<br />
475 If there are still running lanes when the finalizer returns: Lanes will throw a C++ <tt>std::logic_error</tt> if the finalizer returned <tt>"throw"</tt>. Any other value will cause Lanes to freeze forever. 475 If there are still running lanes when the finalizer returns: Lanes will throw a C++ <tt>std::logic_error</tt> if the finalizer returned <tt>"throw"</tt>. Any other value will cause Lanes to freeze forever.
@@ -508,7 +508,7 @@
508<p> 508<p>
509 The function returned by <tt>lanes.gen()</tt> is a "generator" for launching any number of lanes. They will share code, options, initial globals, but the particular arguments may vary. Only calling the generator function actually launches a lane, and provides a handle for controlling it. 509 The function returned by <tt>lanes.gen()</tt> is a "generator" for launching any number of lanes. They will share code, options, initial globals, but the particular arguments may vary. Only calling the generator function actually launches a lane, and provides a handle for controlling it.
510 <br /> 510 <br />
511 Alternatively, <tt>lane_func</tt> may be a string, in which case it will be compiled in the lane. This was to be able to launch lanes with older versions of LuaJIT, which didn't not support <tt>lua_dump</tt>, used internally to transfer functions to the lane. 511 Alternatively, <tt>lane_func</tt> may be a string, in which case it will be compiled in the lane. This was to be able to launch a lane with older versions of LuaJIT, which didn't not support <tt>lua_dump</tt>, used internally to transfer functions to the lane.
512</p> 512</p>
513 513
514<p> 514<p>
@@ -797,7 +797,7 @@
797<h3 id="coroutines">Coroutine lanes</h3> 797<h3 id="coroutines">Coroutine lanes</h3>
798 798
799<p> 799<p>
800 It is possible to have the Lane body run inside the lane as a coroutine. For this, just use <tt>lanes.coro()</tt> instead of <tt>lanes.gen()</tt>. 800 It is possible to have the lane body run inside the lane as a coroutine. For this, just use <tt>lanes.coro()</tt> instead of <tt>lanes.gen()</tt>.
801 801
802 <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> 802 <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
803 <tr> 803 <tr>
@@ -808,7 +808,7 @@
808 </table> 808 </table>
809 809
810 Coroutine lanes function mostly like regular coroutines. They can use <tt>coroutine.yield()</tt> normally, in which case the yielded values can be obtained with regular lane indexing (see <a href="#results">Results and errors</a>).<br /> 810 Coroutine lanes function mostly like regular coroutines. They can use <tt>coroutine.yield()</tt> normally, in which case the yielded values can be obtained with regular lane indexing (see <a href="#results">Results and errors</a>).<br />
811 A yielded coroutine Lane has a <tt>"suspended"</tt> status. It can be resumed with <tt>lane_h:resume(values...)</tt>. 811 A yielded coroutine lane has a <tt>"suspended"</tt> status. It can be resumed with <tt>lane_h:resume(values...)</tt>.
812 <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> 812 <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
813 <tr> 813 <tr>
814 <td> 814 <td>
@@ -921,7 +921,7 @@
921 </td> 921 </td>
922 <td /> 922 <td />
923 <td> 923 <td>
924 Running, not suspended on a <a href="#lindas">Linda</a> call, or yielded on a <tt>coroutine.yield()</tt> call. 924 Running, not suspended on a <a href="#lindas">linda</a> call, or yielded on a <tt>coroutine.yield()</tt> call.
925 </td> 925 </td>
926 </tr> 926 </tr>
927 <tr> 927 <tr>
@@ -955,7 +955,7 @@
955 </td> 955 </td>
956 <td /> 956 <td />
957 <td> 957 <td>
958 Waiting at a <a href="#lindas">Linda</a> <tt>:receive()</tt> or <tt>:send()</tt> 958 Waiting at a <a href="#lindas">linda</a> <tt>:receive()</tt> or <tt>:send()</tt>
959 </td> 959 </td>
960 </tr> 960 </tr>
961 <tr> 961 <tr>
@@ -1076,7 +1076,7 @@
1076</pre></td></tr></table> 1076</pre></td></tr></table>
1077 1077
1078<p> 1078<p>
1079 If you want to wait for multiple lanes to finish (any of a set of lanes), use a <a href="#lindas">Linda</a> object. Give each lane a specific id, and send that id over a <a href="#lindas">Linda</a> once that thread is done (as the last thing you do). 1079 If you want to wait for multiple lanes to finish (any of a set of lanes), use a <a href="#lindas">linda</a> object. Give each lane a specific id, and send that id over a <a href="#lindas">linda</a> once that thread is done (as the last thing you do).
1080</p> 1080</p>
1081 1081
1082<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> 1082<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
@@ -1112,7 +1112,7 @@
1112 <tt>"soft"</tt>: Cancellation will only cause <tt>cancel_test()</tt> to return <tt>true</tt>, so that the lane can cleanup manually. 1112 <tt>"soft"</tt>: Cancellation will only cause <tt>cancel_test()</tt> to return <tt>true</tt>, so that the lane can cleanup manually.
1113 </li> 1113 </li>
1114 <li> 1114 <li>
1115 <tt>"hard"</tt>: waits for the request to be processed, or a timeout to occur. <a href="#lindas">Linda</a> operations detecting the cancellation request will raise a special cancellation error (meaning they won't return in that case).<br /> 1115 <tt>"hard"</tt>: waits for the request to be processed, or a timeout to occur. <a href="#lindas">linda</a> operations detecting the cancellation request will raise a special cancellation error (meaning they won't return in that case).<br />
1116 <tt>wake_lane</tt> defaults to <tt>true</tt>, and <tt>timeout</tt> defaults to 0 if not specified. 1116 <tt>wake_lane</tt> defaults to <tt>true</tt>, and <tt>timeout</tt> defaults to 0 if not specified.
1117 </li> 1117 </li>
1118 <li> 1118 <li>
@@ -1123,7 +1123,7 @@
1123 </li> 1123 </li>
1124 </ul> 1124 </ul>
1125 If <tt>mode</tt> is not specified, it defaults to <tt>"hard"</tt>. 1125 If <tt>mode</tt> is not specified, it defaults to <tt>"hard"</tt>.
1126 If <tt>wake_lane</tt> is <tt>true</tt>, the lane is also signalled so that execution returns from any pending <a href="#lindas">Linda</a> operation. <a href="#lindas">Linda</a> operations detecting the cancellation request return <tt>lanes.cancel_error</tt>. 1126 If <tt>wake_lane</tt> is <tt>true</tt>, the lane is also signalled so that execution returns from any pending <a href="#lindas">linda</a> operation. <a href="#lindas">linda</a> operations detecting the cancellation request return <tt>lanes.cancel_error</tt>.
1127</p> 1127</p>
1128<p> 1128<p>
1129 Returns <tt>true, lane_h.status</tt> if lane was already done (in <tt>"done"</tt>, <tt>"error"</tt> or <tt>"cancelled"</tt> status), or the cancellation was fruitful within <tt>timeout_secs</tt> timeout period.<br /> 1129 Returns <tt>true, lane_h.status</tt> if lane was already done (in <tt>"done"</tt>, <tt>"error"</tt> or <tt>"cancelled"</tt> status), or the cancellation was fruitful within <tt>timeout_secs</tt> timeout period.<br />
@@ -1135,7 +1135,7 @@
1135<p> 1135<p>
1136 Cancellation is tested <u>before</u> going to sleep in <tt>receive()</tt> or <tt>send()</tt> calls and after executing <tt>cancelstep</tt> Lua statements. A pending <tt>receive()</tt>or <tt>send()</tt> call is awakened. 1136 Cancellation is tested <u>before</u> going to sleep in <tt>receive()</tt> or <tt>send()</tt> calls and after executing <tt>cancelstep</tt> Lua statements. A pending <tt>receive()</tt>or <tt>send()</tt> call is awakened.
1137 <br /> 1137 <br />
1138 This means the execution of the lane will resume although the operation has not completed, to give the lane a chance to detect cancellation (even in the case the code waits on a <a href="#lindas">Linda</a> with infinite timeout). 1138 This means the execution of the lane will resume although the operation has not completed, to give the lane a chance to detect cancellation (even in the case the code waits on a <a href="#lindas">linda</a> with infinite timeout).
1139 <br /> 1139 <br />
1140 The code should be able to handle this situation appropriately if required (in other words, it should gracefully handle the fact that it didn't receive the expected values). 1140 The code should be able to handle this situation appropriately if required (in other words, it should gracefully handle the fact that it didn't receive the expected values).
1141 <br /> 1141 <br />
@@ -1192,12 +1192,12 @@
1192 1192
1193<p> 1193<p>
1194 Communications between lanes is completely detached from the lane handles themselves. By itself, a lane can only provide return values once it is finished, or throw an error. 1194 Communications between lanes is completely detached from the lane handles themselves. By itself, a lane can only provide return values once it is finished, or throw an error.
1195 Needs to communicate during runtime are handled by <a href="http://en.wikipedia.org/wiki/Linda_%28coordination_language%29" target="_blank">Linda objects</a>, which are 1195 Needs to communicate during runtime are handled by <a href="http://en.wikipedia.org/wiki/Linda_%28coordination_language%29" target="_blank">linda objects</a>, which are
1196 <a href="#deep_userdata">deep userdata</a> instances. They can be provided to a lane as startup arguments, upvalues or in some other Linda's message. 1196 <a href="#deep_userdata">deep userdata</a> instances. They can be provided to a lane as startup arguments, upvalues or in some other linda's message.
1197</p> 1197</p>
1198 1198
1199<p> 1199<p>
1200 Access to a Linda object means a lane can read or write to any of its data slots. Multiple lanes can be accessing the same Linda simultaneously. Seen from Lua, no application level locking is required; each Linda operation is atomic. 1200 Access to a linda object means a lane can read or write to any of its data slots. Multiple lanes can be accessing the same linda simultaneously. Seen from Lua, no application level locking is required; each linda operation is atomic.
1201</p> 1201</p>
1202 1202
1203<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> 1203<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
@@ -1227,7 +1227,7 @@
1227</pre></td></tr></table> 1227</pre></td></tr></table>
1228 1228
1229<p> 1229<p>
1230 Characteristics of the Lanes implementation of Lindas are: 1230 Characteristics of the Lanes implementation of lindas are:
1231 1231
1232 <ul> 1232 <ul>
1233 <li>Keys can be of boolean, number, string, light userdata, and deep userdata type. Tables and functions can't be keys because their identity isn't preserved when transfered from one Lua state to another.</li> 1233 <li>Keys can be of boolean, number, string, light userdata, and deep userdata type. Tables and functions can't be keys because their identity isn't preserved when transfered from one Lua state to another.</li>
@@ -1245,12 +1245,12 @@
1245 <li>Individual keys' queue length can be limited, balancing speed differences in a producer/consumer scenario (making <tt>:send</tt> wait).</li> 1245 <li>Individual keys' queue length can be limited, balancing speed differences in a producer/consumer scenario (making <tt>:send</tt> wait).</li>
1246 <li><tt>tostring(linda)</tt> returns a string of the form <tt>"Linda: &lt;opt_name&gt;"</tt></li> 1246 <li><tt>tostring(linda)</tt> returns a string of the form <tt>"Linda: &lt;opt_name&gt;"</tt></li>
1247 <li> 1247 <li>
1248 Several Linda objects may share the same <a href="#keepers">Keeper state</a>. In case there is more than one user <a href="#keepers">Keeper state</a>, assignation must be controlled with the Linda's group (an integer in <tt>[0,nb_user_keepers]</tt>). 1248 Several linda objects may share the same <a href="#keepers">Keeper state</a>. In case there is more than one user <a href="#keepers">Keeper state</a>, assignation must be controlled with the linda's group (an integer in <tt>[0,nb_user_keepers]</tt>).
1249 Lanes has an internal Linda used for timers and <tt>lanes.wait</tt>; this Linda uses group 0. 1249 Lanes has an internal linda used for timers and <tt>lanes.wait</tt>; this linda uses group 0.
1250 </li> 1250 </li>
1251 <li> 1251 <li>
1252 IMPORTANT: *all* Linda operations are wrapped inside a <tt>lua_gc STOP/RESTART</tt> pair. 1252 IMPORTANT: *all* linda operations are wrapped inside a <tt>lua_gc STOP/RESTART</tt> pair.
1253 This is to prevent potential collection of a Linda during another Linda's operation, as this can cause a crash if they are bound to the same <a href="#keepers">Keeper state</a>. 1253 This is to prevent potential collection of a linda during another linda's operation, as this can cause a crash if they are bound to the same <a href="#keepers">Keeper state</a>.
1254 </li> 1254 </li>
1255 </ul> 1255 </ul>
1256</p> 1256</p>
@@ -1261,11 +1261,11 @@
1261 1261
1262<p> 1262<p>
1263 Arguments to <tt>lanes.linda()</tt> can be provided in any order, as long as there is a single string, a single number, and a single callable value (all are optional).<br /> 1263 Arguments to <tt>lanes.linda()</tt> can be provided in any order, as long as there is a single string, a single number, and a single callable value (all are optional).<br />
1264 Converting the Linda to a string will yield the provided name prefixed by <tt>"Linda: "</tt>.<br /> 1264 Converting the linda to a string will yield the provided name prefixed by <tt>"Linda: "</tt>.<br />
1265 If <tt>opt_name</tt> is omitted, it will evaluate to an hexadecimal number uniquely representing that Linda when the Linda is converted to a string. The value is the same as returned by <tt>linda:deep()</tt>.<br /> 1265 If <tt>opt_name</tt> is omitted, it will evaluate to an hexadecimal number uniquely representing that linda when the linda is converted to a string. The value is the same as returned by <tt>linda:deep()</tt>.<br />
1266 If <tt>opt_name</tt> is <tt>"auto"</tt>, Lanes will try to construct a name from the source location that called <tt>lanes.linda()</tt>. If that fails, the Linda name will be <tt>"&lt;unresolved&gt;"</tt>.<br /> 1266 If <tt>opt_name</tt> is <tt>"auto"</tt>, Lanes will try to construct a name from the source location that called <tt>lanes.linda()</tt>. If that fails, the linda name will be <tt>"&lt;unresolved&gt;"</tt>.<br />
1267 If Lanes is configured with more than one Keeper state, <tt>group</tt> is mandatory.<br /> 1267 If Lanes is configured with more than one Keeper state, <tt>group</tt> is mandatory.<br />
1268 If the Linda is to-be-closed (Lua 5.4+), and a <tt>close_handler</tt> is provided, it will be called with all the provided arguments. For older Lua versions, its presence will cause an error. 1268 If the linda is to-be-closed (Lua 5.4+), and a <tt>close_handler</tt> is provided, it will be called with all the provided arguments. For older Lua versions, its presence will cause an error.
1269</p> 1269</p>
1270 1270
1271<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> 1271<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
@@ -1276,10 +1276,10 @@
1276<p> 1276<p>
1277 By default, queue sizes are unlimited but limits can be enforced using the <tt>limit()</tt> method. This can be useful to balance execution speeds in a producer/consumer scenario.<br /> 1277 By default, queue sizes are unlimited but limits can be enforced using the <tt>limit()</tt> method. This can be useful to balance execution speeds in a producer/consumer scenario.<br />
1278 A limit of 0 is allowed to block everything. <tt>"unlimited"</tt> removes the limit.<br /> 1278 A limit of 0 is allowed to block everything. <tt>"unlimited"</tt> removes the limit.<br />
1279 If the key was full but the limit change added some room, <tt>limit()</tt> first return value is <tt>true</tt> and the Linda is signalled so that <tt>send()</tt>-blocked threads are awakened, else the return value is <tt>false</tt>. 1279 If the key was full but the limit change added some room, <tt>limit()</tt> first return value is <tt>true</tt> and the linda is signalled so that <tt>send()</tt>-blocked threads are awakened, else the return value is <tt>false</tt>.
1280 If no limit is provided, <tt>limit()</tt> first return value is the current limit for the specified key.<br /> 1280 If no limit is provided, <tt>limit()</tt> first return value is the current limit for the specified key.<br />
1281 The second returned value is a string representing the fill status relatively to the key's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>). 1281 The second returned value is a string representing the fill status relatively to the key's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>).
1282 Whether reading or writing, if the Linda is cancelled, <tt>limit()</tt> returns <tt>nil, lanes.cancel_error</tt>. 1282 Whether reading or writing, if the linda is cancelled, <tt>limit()</tt> returns <tt>nil, lanes.cancel_error</tt>.
1283</p> 1283</p>
1284 1284
1285<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> 1285<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
@@ -1288,7 +1288,7 @@
1288 1288
1289<p> 1289<p>
1290 Timeouts are given in seconds (&gt= 0, millisecond accuracy) or <tt>nil</tt>. Timeout can be omitted only if the first key is not a number (then it is equivalent to an infinite duration).<br /> 1290 Timeouts are given in seconds (&gt= 0, millisecond accuracy) or <tt>nil</tt>. Timeout can be omitted only if the first key is not a number (then it is equivalent to an infinite duration).<br />
1291 Each key acts as a FIFO queue. There is no limit to the number of keys a Linda may contain. Different Lindas can have identical keys, which are totally unrelated. 1291 Each key acts as a FIFO queue. There is no limit to the number of keys a linda may contain. Different lindas can have identical keys, which are totally unrelated.
1292</p> 1292</p>
1293 1293
1294<p> 1294<p>
@@ -1298,7 +1298,7 @@
1298 1298
1299<p> 1299<p>
1300 If no data is provided after the key, <tt>send()</tt> raises an error.<br /> 1300 If no data is provided after the key, <tt>send()</tt> raises an error.<br />
1301 Also, if <tt>linda.null</tt> or <tt>lanes.null</tt> is sent as data in a Linda, it will be read as a <tt>nil</tt>.<br /> 1301 Also, if <tt>linda.null</tt> or <tt>lanes.null</tt> is sent as data in a linda, it will be read as a <tt>nil</tt>.<br />
1302 <tt>send()</tt> return values can be: 1302 <tt>send()</tt> return values can be:
1303 <ul> 1303 <ul>
1304 <li><tt>true</tt> on success.</li> 1304 <li><tt>true</tt> on success.</li>
@@ -1328,11 +1328,11 @@
1328</p> 1328</p>
1329 1329
1330<p> 1330<p>
1331 Note that any number of lanes can be reading or writing a Linda. There can be many producers, and many consumers. It is up to you. 1331 Note that any number of lanes can be reading or writing a linda. There can be many producers, and many consumers. It is up to you.
1332</p> 1332</p>
1333 1333
1334<p> 1334<p>
1335 Remember that <a href="#cancelling">Hard cancellation</a> will cause pending Linda operations to abort execution of the lane through a cancellation error. This means that you have to install a <a href="#finalizers">finalizer</a> in your lane if you want to run some code in that situation. 1335 Remember that <a href="#cancelling">Hard cancellation</a> will cause pending linda operations to abort execution of the lane through a cancellation error. This means that you have to install a <a href="#finalizers">finalizer</a> in your lane if you want to run some code in that situation.
1336</p> 1336</p>
1337 1337
1338<p> 1338<p>
@@ -1359,15 +1359,15 @@
1359</p> 1359</p>
1360<p> 1360<p>
1361 <tt>set()</tt> can write several values at the specified key. Writing <tt>nil</tt> values is possible, and clearing the contents at the specified key is done by not providing any value.<br /> 1361 <tt>set()</tt> can write several values at the specified key. Writing <tt>nil</tt> values is possible, and clearing the contents at the specified key is done by not providing any value.<br />
1362 If <tt>set()</tt> actually stores data, the Linda is signalled for write, so that <tt>receive()</tt>-blocked Lanes are awakened.<br /> 1362 If <tt>set()</tt> actually stores data, the linda is signalled for write, so that <tt>receive()</tt>-blocked Lanes are awakened.<br />
1363 Clearing the contents of a non-existent key does not create it!<br /> 1363 Clearing the contents of a non-existent key does not create it!<br />
1364 If the key was full but the new data count of the key after <tt>set()</tt> is below its limit, <tt>set()</tt> first return value is <tt>true</tt> and the Linda is also signaled for read, so that <tt>send()</tt>-blocked Lanes are awakened.<br /> 1364 If the key was full but the new data count of the key after <tt>set()</tt> is below its limit, <tt>set()</tt> first return value is <tt>true</tt> and the linda is also signaled for read, so that <tt>send()</tt>-blocked Lanes are awakened.<br />
1365 If the key was not already full, nothing additional happens, and <tt>set()</tt> first return value is <tt>false</tt>.<br /> 1365 If the key was not already full, nothing additional happens, and <tt>set()</tt> first return value is <tt>false</tt>.<br />
1366 The second return value is a string representing the fill status relatively to the key's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>). 1366 The second return value is a string representing the fill status relatively to the key's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>).
1367</p> 1367</p>
1368 1368
1369<p> 1369<p>
1370 Trying to send or receive data through a cancelled Linda does nothing and returns <tt>lanes.cancel_error</tt>. 1370 Trying to send or receive data through a cancelled linda does nothing and returns <tt>lanes.cancel_error</tt>.
1371</p> 1371</p>
1372 1372
1373<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> 1373<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
@@ -1375,9 +1375,9 @@
1375</pre></td></tr></table> 1375</pre></td></tr></table>
1376 1376
1377<p> 1377<p>
1378 Returns some information about the contents of the Linda.<br /> 1378 Returns some information about the contents of the linda.<br />
1379 If no key is specified, and the Linda is empty, returns nothing.<br /> 1379 If no key is specified, and the linda is empty, returns nothing.<br />
1380 If no key is specified, and the Linda is not empty, returns a table of key/count pairs that counts the number of items in each of the exiting keys of the Linda. This count can be 0 if the key has been used but is empty.<br /> 1380 If no key is specified, and the linda is not empty, returns a table of key/count pairs that counts the number of items in each of the exiting keys of the linda. This count can be 0 if the key has been used but is empty.<br />
1381 If a single key is specified, returns the number of pending items, or nothing if the key is unknown.<br /> 1381 If a single key is specified, returns the number of pending items, or nothing if the key is unknown.<br />
1382 If more than one key is specified, return a table of key/count pairs for the known keys. 1382 If more than one key is specified, return a table of key/count pairs for the known keys.
1383</p> 1383</p>
@@ -1397,8 +1397,8 @@
1397</pre></td></tr></table> 1397</pre></td></tr></table>
1398 1398
1399<p> 1399<p>
1400 Returns a table describing the full contents of a Linda, or <tt>nil</tt> if the Linda wasn't used yet.<br /> 1400 Returns a table describing the full contents of a linda, or <tt>nil</tt> if the linda wasn't used yet.<br />
1401 If Decoda support is enabled with <tt>HAVE_DECODA_SUPPORT()</tt>, <a Linda metatable contain a <tt>__towatch</tt> special function that generates a similar table used for debug display. 1401 If Decoda support is enabled with <tt>HAVE_DECODA_SUPPORT()</tt>, the linda metatable contains a <tt>__towatch</tt> special function that generates a similar table used for debug display.
1402</p> 1402</p>
1403 1403
1404<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> 1404<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
@@ -1406,10 +1406,10 @@
1406</pre></td></tr></table> 1406</pre></td></tr></table>
1407 1407
1408<p> 1408<p>
1409 Signals the Linda so that lanes waiting for read, write, or both, wake up. 1409 Signals the linda so that lanes waiting for read, write, or both, wake up.
1410 All Linda operations (including <tt>get()</tt> and <tt>set()</tt>) will return <tt>lanes.cancel_error</tt> as when the calling lane is <a href="#cancelling">soft-cancelled</a> as long as the Linda is marked as cancelled.<br /> 1410 All linda operations (including <tt>get()</tt> and <tt>set()</tt>) will return <tt>lanes.cancel_error</tt> as when the calling lane is <a href="#cancelling">soft-cancelled</a> as long as the linda is marked as cancelled.<br />
1411 <tt>"none"</tt> reset the Linda's cancel status, but doesn't signal it.<br /> 1411 <tt>"none"</tt> reset the linda's cancel status, but doesn't signal it.<br />
1412 If not void, the lane's cancel status overrides the Linda's cancel status. 1412 If not void, the lane's cancel status overrides the linda's cancel status.
1413</p> 1413</p>
1414 1414
1415<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> 1415<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
@@ -1417,48 +1417,48 @@
1417</pre></td></tr></table> 1417</pre></td></tr></table>
1418 1418
1419<p> 1419<p>
1420 Returns a light userdata that uniquely represents the Linda. The stored value is the same as what is seen when converting an unnamed Linda to a string. 1420 Returns a light userdata that uniquely represents the linda. The stored value is the same as what is seen when converting an unnamed linda to a string.
1421</p> 1421</p>
1422 1422
1423<h3 id="keepers">Granularity of using Lindas</h3> 1423<h3 id="keepers">Granularity of using lindas</h3>
1424 1424
1425<p> 1425<p>
1426 A Linda is a gateway to read and write data inside some hidden Lua states, called keeper states. Lindas are hashed to a fixed number of keeper states, which are a locking entity.<br /> 1426 A linda is a gateway to read and write data inside some hidden Lua states, called keeper states. Lindas are hashed to a fixed number of keeper states, which are a locking entity.<br />
1427 The data sent through a Linda is stored inside the associated keeper state in a Lua table where each Linda slot is the key to another table containing a FIFO for that slot.<br /> 1427 The data sent through a linda is stored inside the associated keeper state in a Lua table where each linda slot is the key to another table containing a FIFO for that slot.<br />
1428 Each keeper state is associated with an OS mutex, to prevent concurrent access to the keeper state. The Linda itself uses two signals to be made aware of operations occuring on it.<br /> 1428 Each keeper state is associated with an OS mutex, to prevent concurrent access to the keeper state. The linda itself uses two signals to be made aware of operations occuring on it.<br />
1429 Whenever Lua code reads from or writes to a Linda, the mutex is acquired. If Linda limits don't block the operation, it is fulfilled, then the mutex is released.<br /> 1429 Whenever Lua code reads from or writes to a linda, the mutex is acquired. If linda limits don't block the operation, it is fulfilled, then the mutex is released.<br />
1430 If the Linda has to block, the mutex is released and the OS thread sleeps, waiting for a Linda operation to be signalled. When an operation occurs on the same Linda, possibly fufilling the condition, or a timeout expires, the thread wakes up.<br /> 1430 If the linda has to block, the mutex is released and the OS thread sleeps, waiting for a linda operation to be signalled. When an operation occurs on the same linda, possibly fufilling the condition, or a timeout expires, the thread wakes up.<br />
1431 If the thread is woken but the condition is not yet fulfilled, it goes back to sleep, until the timeout expires.<br /> 1431 If the thread is woken but the condition is not yet fulfilled, it goes back to sleep, until the timeout expires.<br />
1432 When a lane is cancelled, the signal it is waiting on (if any) is signalled. In that case, the Linda operation will return <tt>lanes.cancel_error</tt>.<br /> 1432 When a lane is cancelled, the signal it is waiting on (if any) is signalled. In that case, the linda operation will return <tt>lanes.cancel_error</tt>.<br />
1433</p> 1433</p>
1434 1434
1435<p> 1435<p>
1436 A single Linda object provides an infinite number of slots, so why would you want to use several? 1436 A single linda object provides an infinite number of slots, so why would you want to use several?
1437</p> 1437</p>
1438 1438
1439<p> 1439<p>
1440 There are some important reasons: 1440 There are some important reasons:
1441 <ul> 1441 <ul>
1442 <li> 1442 <li>
1443 Access control. If you don't trust certain code completely, or just to modularize your design, use one Linda for one usage and another one 1443 Access control. If you don't trust certain code completely, or just to modularize your design, use one linda for one usage and another one
1444 for the other. This keeps your code clear and readable. You can pass multiple Linda handles to a lane with practically no added cost. 1444 for the other. This keeps your code clear and readable. You can pass multiple linda handles to a lane with practically no added cost.
1445 </li> 1445 </li>
1446 1446
1447 <li> 1447 <li>
1448 Namespace control. Linda keys have a "flat" namespace, so collisions are possible if you try to use the same Linda for too many separate uses. 1448 Namespace control. linda keys have a "flat" namespace, so collisions are possible if you try to use the same linda for too many separate uses.
1449 </li> 1449 </li>
1450 1450
1451 <li> 1451 <li>
1452 Performance. Changing any slot in a Linda causes all pending threads for that Linda to be momentarily awakened (at least in the C level). 1452 Performance. Changing any slot in a linda causes all pending threads for that linda to be momentarily awakened (at least in the C level).
1453 This can degrade performance due to unnecessary OS level context switches. The more Keeper states you declared with <a href="#initialization"><tt>lanes.configure()</tt></a> the less this should be a problem. 1453 This can degrade performance due to unnecessary OS level context switches. The more Keeper states you declared with <a href="#initialization"><tt>lanes.configure()</tt></a> the less this should be a problem.
1454 </li> 1454 </li>
1455 </ul> 1455 </ul>
1456 1456
1457On the other side, you need to use a common Linda for waiting for multiple keys. You cannot wait for keys from two separate Linda objects at the same time. 1457 On the other side, you need to use a common linda for waiting for multiple keys. You cannot wait for keys from two separate linda objects at the same time.
1458</p> 1458</p>
1459 1459
1460<p> 1460<p>
1461<font size="-1">Actually, you can. Make separate lanes to wait each, and then multiplex those events to a common Linda, but... :).</font> 1461 <font size="-1">Actually, you can. Make separate lanes to wait each, and then multiplex those events to a common linda, but... :).</font>
1462</p> 1462</p>
1463 1463
1464 1464
@@ -1479,7 +1479,7 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1479</p> 1479</p>
1480 1480
1481<p> 1481<p>
1482 Once a timer expires, the <tt>key</tt> is set with the current time (in seconds, same offset as <tt>os.time()</tt> but with millisecond accuracy). The key can be waited upon using the regular <a href="#lindas">Linda</a> <tt>:receive()</tt> method. 1482 Once a timer expires, the <tt>key</tt> is set with the current time (in seconds, same offset as <tt>os.time()</tt> but with millisecond accuracy). The key can be waited upon using the regular <a href="#lindas">linda</a> <tt>:receive()</tt> method.
1483</p> 1483</p>
1484 1484
1485<p> 1485<p>
@@ -1518,10 +1518,10 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1518 <td valign=top><i><nobr>Design note:</nobr></i></td> 1518 <td valign=top><i><nobr>Design note:</nobr></i></td>
1519 <td> 1519 <td>
1520 <font size="-1"> 1520 <font size="-1">
1521 Having the API as <tt>lanes.timer()</tt> is intentional. Another alternative would be <tt>linda_h:timer()</tt> but timers are not traditionally seen to be part of Lindas. Also, it would mean any lane getting a <a href="#lindas">Linda</a> handle would be able to modify timers on it. 1521 Having the API as <tt>lanes.timer()</tt> is intentional. Another alternative would be <tt>linda_h:timer()</tt> but timers are not traditionally seen to be part of lindas. Also, it would mean any lane getting a <a href="#lindas">linda</a> handle would be able to modify timers on it.
1522 A third choice could be abstracting the timers out of <a href="#lindas">Linda</a> realm altogether (<tt>timer_h= lanes.timer(date|first_secs, period_secs )</tt>) but that would mean separate waiting functions for timers, and lindas. 1522 A third choice could be abstracting the timers out of <a href="#lindas">linda</a> realm altogether (<tt>timer_h= lanes.timer(date|first_secs, period_secs )</tt>) but that would mean separate waiting functions for timers, and lindas.
1523 Even if a <a href="#lindas">Linda</a> object and key was returned, that key couldn't be waited upon simultaneously with one's general <a href="#lindas">Linda</a> events. 1523 Even if a <a href="#lindas">linda</a> object and key was returned, that key couldn't be waited upon simultaneously with one's general <a href="#lindas">linda</a> events.
1524 The current system gives maximum capabilities with minimum API, and any smoothenings can easily be crafted in Lua at the application level. 1524 The current system gives maximum capabilities with minimum API, and any smoothenings can easily be crafted in Lua at the application level.
1525 </font> 1525 </font>
1526 </td> 1526 </td>
1527 </tr> 1527 </tr>
@@ -1543,7 +1543,7 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1543</pre></td></tr></table> 1543</pre></td></tr></table>
1544 1544
1545<p> 1545<p>
1546 A very simple way of sleeping when nothing else is available. Is implemented by attempting to read some data in an unused channel of the internal <a href="#lindas">Linda</a> used for timers (this <a href="#lindas">Linda</a> exists even when timers aren't enabled). 1546 A very simple way of sleeping when nothing else is available. Is implemented by attempting to read some data in an unused channel of the internal <a href="#lindas">linda</a> used for timers (this <a href="#lindas">linda</a> exists even when timers aren't enabled).
1547 Default duration is 0, which should only cause a thread context switch.<br /> 1547 Default duration is 0, which should only cause a thread context switch.<br />
1548 Return values should always be <tt>nil, "timeout"</tt> (or <tt>nil, lanes.cancel_error</tt> in case of interruption). 1548 Return values should always be <tt>nil, "timeout"</tt> (or <tt>nil, lanes.cancel_error</tt> in case of interruption).
1549</p> 1549</p>
@@ -1553,7 +1553,7 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1553</pre></td></tr></table> 1553</pre></td></tr></table>
1554 1554
1555<p> 1555<p>
1556 Returns the current value of the clock used by timers and <a href="#lindas">Linda</a> objects. 1556 Returns the current value of the clock used by timers and <a href="#lindas">linda</a> objects.
1557</p> 1557</p>
1558 1558
1559<!-- locks +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 1559<!-- locks +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@@ -1575,7 +1575,7 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1575<p> 1575<p>
1576 The generated function acquires M tokens from the N available, or releases them if the value is negative. The acquiring call will suspend the lane, if necessary. Use <tt>M=N=1</tt> for a critical section lock (only one lane allowed to enter). 1576 The generated function acquires M tokens from the N available, or releases them if the value is negative. The acquiring call will suspend the lane, if necessary. Use <tt>M=N=1</tt> for a critical section lock (only one lane allowed to enter).
1577 <br /> 1577 <br />
1578 When passsing <tt>"try"</tt> as second argument when acquiring, then <tt>lock_func</tt> operates on the <a href="#lindas">Linda</a> with a timeout of 0 to emulate a TryLock() operation. If locking fails, <tt>lock_func</tt> returns <tt>false</tt>. <tt>"try"</tt> is ignored when releasing (as it it not expected to ever have to wait unless the acquisition/release pairs are not properly matched). 1578 When passsing <tt>"try"</tt> as second argument when acquiring, then <tt>lock_func</tt> operates on the <a href="#lindas">linda</a> with a timeout of 0 to emulate a TryLock() operation. If locking fails, <tt>lock_func</tt> returns <tt>false</tt>. <tt>"try"</tt> is ignored when releasing (as it it not expected to ever have to wait unless the acquisition/release pairs are not properly matched).
1579 <br /> 1579 <br />
1580 Upon successful lock/unlock, <tt>lock_func</tt> returns <tt>true</tt> (always the case when block-waiting for completion). 1580 Upon successful lock/unlock, <tt>lock_func</tt> returns <tt>true</tt> (always the case when block-waiting for completion).
1581</p> 1581</p>
@@ -1612,14 +1612,14 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1612<h3>Limitations on data passing</h3> 1612<h3>Limitations on data passing</h3>
1613 1613
1614<p> 1614<p>
1615 Data passed between lanes (either as starting arguments, return values, upvalues or via Lindas) must conform to the following: 1615 Data passed between lanes (either as starting arguments, return values, upvalues or via lindas) must conform to the following:
1616 <ul> 1616 <ul>
1617 <li>Coroutines cannot be passed. A coroutine's Lua state is tied to the Lua state that created it, and there is no way the mixed C/Lua stack of a coroutine can be transfered from one Lua state to another.</li> 1617 <li>Coroutines cannot be passed. A coroutine's Lua state is tied to the Lua state that created it, and there is no way the mixed C/Lua stack of a coroutine can be transfered from one Lua state to another.</li>
1618 <li>Lane handles cannot be passed between lanes.</li> 1618 <li>Lane handles cannot be passed between lanes.</li>
1619 <li>Booleans, numbers, strings, light userdata, Lua functions and tables of such can always be passed.</li> 1619 <li>Booleans, numbers, strings, light userdata, Lua functions and tables of such can always be passed.</li>
1620 <li> 1620 <li>
1621 Cyclic tables and/or duplicate references are allowed and reproduced appropriately, but only <u>within the same transmission</u>. 1621 Cyclic tables and/or duplicate references are allowed and reproduced appropriately, but only <u>within the same transmission</u>.
1622 Using the same source table in multiple <a href="#lindas">Linda</a> messages keeps no ties between the tables (this is the same reason why tables can't be used as keys). 1622 Using the same source table in multiple <a href="#lindas">linda</a> messages keeps no ties between the tables (this is the same reason why tables can't be used as keys).
1623 </li> 1623 </li>
1624 <li> 1624 <li>
1625 For tables and full userdata: before anything else, the metatable is searched for a <tt>__lanesconvert</tt> field. If found, the source object is converted as follows depending on <tt>__lanesconvert</tt>'s value: 1625 For tables and full userdata: before anything else, the metatable is searched for a <tt>__lanesconvert</tt> field. If found, the source object is converted as follows depending on <tt>__lanesconvert</tt>'s value:
@@ -1706,7 +1706,7 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1706 </li> 1706 </li>
1707 </ul> 1707 </ul>
1708 Another more immediate reason of failed transfer is when the destination state doesn't know about the C function that has to be transferred. This occurs if a function is transferred in a lane before it had a chance to scan the module. 1708 Another more immediate reason of failed transfer is when the destination state doesn't know about the C function that has to be transferred. This occurs if a function is transferred in a lane before it had a chance to scan the module.
1709 If the C function is sent through a <a href="#lindas">Linda</a>, it is enough for the destination lane body to have required the module before the function is sent. 1709 If the C function is sent through a <a href="#lindas">linda</a>, it is enough for the destination lane body to have required the module before the function is sent.
1710 But if the lane body provided to the generator has a C function as upvalue, the transfer itself must succeed, therefore the module that imported that C function must be required in the destination lane before the lane body starts executing. This is where the <a href = "#.required"><tt>.required</tt></a> options play their role. 1710 But if the lane body provided to the generator has a C function as upvalue, the transfer itself must succeed, therefore the module that imported that C function must be required in the destination lane before the lane body starts executing. This is where the <a href = "#.required"><tt>.required</tt></a> options play their role.
1711</p> 1711</p>
1712 1712
@@ -1810,7 +1810,7 @@ int luaD_new_clonable(lua_State* L)
1810<h3 id="deep_userdata">Deep userdata in your own apps</h3> 1810<h3 id="deep_userdata">Deep userdata in your own apps</h3>
1811 1811
1812<p> 1812<p>
1813 The mechanism Lanes uses for sharing <a href="#lindas">Linda</a> handles between separate Lua states can be used for custom userdata as well. Here's what to do. 1813 The mechanism Lanes uses for sharing <a href="#lindas">linda</a> handles between separate Lua states can be used for custom userdata as well. Here's what to do.
1814</p> 1814</p>
1815 1815
1816<ol> 1816<ol>
@@ -1848,7 +1848,7 @@ static MyDeepFactory g_MyDeepFactory;
1848</p> 1848</p>
1849 1849
1850<p> 1850<p>
1851 Deep userdata in transit inside <a href="#keepers">Keeper states</a> (sent in a <a href="#lindas">Linda</a> but not yet consumed) don't call <tt>deleteDeepObjectInternal</tt> and aren't considered by reference counting. The rationale is the following:<br /> 1851 Deep userdata in transit inside <a href="#keepers">Keeper states</a> (sent in a <a href="#lindas">linda</a> but not yet consumed) don't call <tt>deleteDeepObjectInternal</tt> and aren't considered by reference counting. The rationale is the following:<br />
1852 If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0.<br /> 1852 If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0.<br />
1853 OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's <tt>factory()</tt> interface is never accessed from a keeper state.<br /> 1853 OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's <tt>factory()</tt> interface is never accessed from a keeper state.<br />
1854 Therefore, Lanes can just call <tt>deleteDeepObjectInternal</tt> when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in <a href="#keepers">Keeper states</a> now hold stale pointers. 1854 Therefore, Lanes can just call <tt>deleteDeepObjectInternal</tt> when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in <a href="#keepers">Keeper states</a> now hold stale pointers.
@@ -1866,7 +1866,7 @@ static MyDeepFactory g_MyDeepFactory;
1866</p> 1866</p>
1867 1867
1868<p> 1868<p>
1869 The same benefits can be achieved by having a single worker lane spawn all the sublanes, and keep track of them. Communications to and from this lane can be handled via a <a href="#lindas">Linda</a>. 1869 The same benefits can be achieved by having a single worker lane spawn all the sublanes, and keep track of them. Communications to and from this lane can be handled via a <a href="#lindas">linda</a>.
1870</p> 1870</p>
1871 1871
1872 1872
@@ -1894,12 +1894,12 @@ static MyDeepFactory g_MyDeepFactory;
1894 1894
1895<p> 1895<p>
1896 <ul> 1896 <ul>
1897 <li>Data passing (arguments, upvalues, <a href="#lindas">Linda</a> messages) is generally fast, doing two binary state-to-state copies (from source state to hidden state, hidden state to target state). Remember that not only the function you specify but also its upvalues, their upvalues, etc. etc. will get copied.</li> 1897 <li>Data passing (arguments, upvalues, <a href="#lindas">linda</a> messages) is generally fast, doing two binary state-to-state copies (from source state to hidden state, hidden state to target state). Remember that not only the function you specify but also its upvalues, their upvalues, etc. etc. will get copied.</li>
1898 <li>Lane startup is fast (1000's of lanes a second), depending on the number of standard libraries initialized. Initializing all standard libraries is about 3-4 times slower than having no standard libraries at all. If you throw in a lot of lanes per second, make sure you give them minimal necessary set of libraries.</li> 1898 <li>Lane startup is fast (1000's of lanes a second), depending on the number of standard libraries initialized. Initializing all standard libraries is about 3-4 times slower than having no standard libraries at all. If you throw in a lot of lanes per second, make sure you give them minimal necessary set of libraries.</li>
1899 <li>Waiting Lindas are woken up (and execute some hidden Lua code) each time <u>any</u> key in the <a href="#lindas">Lindas</a> they are waiting for are changed. This may give essential slow-down (not measured, just a gut feeling) if a lot of <a href="#lindas">Linda</a> keys are used. Using separate <a href="#lindas">Lindas</a> for logically separate issues will help (which is good practice anyhow).</li> 1899 <li>Waiting lindas are woken up (and execute some hidden Lua code) each time <u>any</u> key in the <a href="#lindas">lindas</a> they are waiting for are changed. This may give essential slow-down (not measured, just a gut feeling) if a lot of <a href="#lindas">linda</a> keys are used. Using separate <a href="#lindas">lindas</a> for logically separate issues will help (which is good practice anyhow).</li>
1900 <li><a href="#lindas">Linda</a> objects are light. The memory footprint is two OS-level signalling objects (<tt>HANDLE</tt> or <tt>pthread_cond_t</tt>) for each, plus one C pointer for the proxies per each Lua state using the <a href="#lindas">Linda</a>. Barely nothing.</li> 1900 <li><a href="#lindas">linda</a> objects are light. The memory footprint is two OS-level signalling objects (<tt>HANDLE</tt> or <tt>pthread_cond_t</tt>) for each, plus one C pointer for the proxies per each Lua state using the <a href="#lindas">linda</a>. Barely nothing.</li>
1901 <li>Timers are light. You can probably expect timers up to 0.01 second resolution to be useful, but that is very system specific. All timers are merged into one main timer state (see <tt>timer.lua</tt>); no OS side timers are utilized.</li> 1901 <li>Timers are light. You can probably expect timers up to 0.01 second resolution to be useful, but that is very system specific. All timers are merged into one main timer state (see <tt>timer.lua</tt>); no OS side timers are utilized.</li>
1902 <li>If you are using a lot of <a href="#lindas">Linda</a> objects, it may be useful to try having more of these <a href="#keepers">Keeper states</a>. By default, only one is used (see <a href="#initialization"><tt>lanes.configure()</tt></a>).</li> 1902 <li>If you are using a lot of <a href="#lindas">linda</a> objects, it may be useful to try having more of these <a href="#keepers">Keeper states</a>. By default, only one is used (see <a href="#initialization"><tt>lanes.configure()</tt></a>).</li>
1903</ul> 1903</ul>
1904</p> 1904</p>
1905 1905
@@ -1908,7 +1908,7 @@ static MyDeepFactory g_MyDeepFactory;
1908 1908
1909<p> 1909<p>
1910 Cancellation of lanes uses the Lua error mechanism with a special lightuserdata error sentinel. 1910 Cancellation of lanes uses the Lua error mechanism with a special lightuserdata error sentinel.
1911 If you use <tt>pcall</tt> in code that needs to be cancellable from the outside, the special error might not get through to Lanes, thus preventing the Lane from being cleanly cancelled. 1911 If you use <tt>pcall</tt> in code that needs to be cancellable from the outside, the special error might not get through to Lanes, thus preventing the lane from being cleanly cancelled.
1912 You should throw any lightuserdata error further. 1912 You should throw any lightuserdata error further.
1913</p> 1913</p>
1914 1914