diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-07-30 16:34:26 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-07-30 16:34:26 +0200 |
commit | 73813e8fd4104ba4cc56fc66180fb8408f289ba0 (patch) | |
tree | 41cda31201acaeeb8489011240ba4b02af05b2da /docs | |
parent | 6d9c547732506f0a8b006754bb9709699b05e6af (diff) | |
download | lanes-73813e8fd4104ba4cc56fc66180fb8408f289ba0.tar.gz lanes-73813e8fd4104ba4cc56fc66180fb8408f289ba0.tar.bz2 lanes-73813e8fd4104ba4cc56fc66180fb8408f289ba0.zip |
Fix index.html
Diffstat (limited to 'docs')
-rw-r--r-- | docs/index.html | 166 |
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: <opt_name>"</tt></li> | 1246 | <li><tt>tostring(linda)</tt> returns a string of the form <tt>"Linda: <opt_name>"</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>"<unresolved>"</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>"<unresolved>"</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 (>= 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 (>= 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 | ||
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. | 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 | ||