diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/index.css | 29 | ||||
| -rw-r--r-- | docs/index.html | 911 | ||||
| -rw-r--r-- | docs/lua.css | 162 | ||||
| -rw-r--r-- | docs/manual.css | 21 |
4 files changed, 663 insertions, 460 deletions
diff --git a/docs/index.css b/docs/index.css new file mode 100644 index 0000000..6a6e163 --- /dev/null +++ b/docs/index.css | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | ul { | ||
| 2 | list-style-type: none ; | ||
| 3 | } | ||
| 4 | |||
| 5 | ul.contents { | ||
| 6 | padding: 0 ; | ||
| 7 | } | ||
| 8 | |||
| 9 | table { | ||
| 10 | border: none ; | ||
| 11 | border-spacing: 0 ; | ||
| 12 | border-collapse: collapse ; | ||
| 13 | } | ||
| 14 | |||
| 15 | td { | ||
| 16 | vertical-align: top ; | ||
| 17 | padding: 0 ; | ||
| 18 | text-align: left ; | ||
| 19 | line-height: 1.25 ; | ||
| 20 | width: 15% ; | ||
| 21 | } | ||
| 22 | |||
| 23 | table.striped tr:nth-child(even) { | ||
| 24 | background-color: #E8E8E8 ; | ||
| 25 | } | ||
| 26 | |||
| 27 | table.striped tr:nth-child(odd) { | ||
| 28 | background-color: #F4F4F4 ; | ||
| 29 | } | ||
diff --git a/docs/index.html b/docs/index.html index a36119e..63dfedc 100644 --- a/docs/index.html +++ b/docs/index.html | |||
| @@ -9,6 +9,11 @@ | |||
| 9 | <meta name="keywords" content="Lua, Library, Multithreading, Threads, Rocks" /> | 9 | <meta name="keywords" content="Lua, Library, Multithreading, Threads, Rocks" /> |
| 10 | 10 | ||
| 11 | <title>Lua Lanes - multithreading in Lua</title> | 11 | <title>Lua Lanes - multithreading in Lua</title> |
| 12 | |||
| 13 | <link rel="stylesheet" type="text/css" href="lua.css" /> | ||
| 14 | <link rel="stylesheet" type="text/css" href="manual.css" /> | ||
| 15 | <link rel="stylesheet" type="text/css" href="index.css" /> | ||
| 16 | <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> | ||
| 12 | </head> | 17 | </head> |
| 13 | 18 | ||
| 14 | <body> | 19 | <body> |
| @@ -19,7 +24,7 @@ | |||
| 19 | <center> | 24 | <center> |
| 20 | <table summary="Lua logo"><tbody> | 25 | <table summary="Lua logo"><tbody> |
| 21 | <tr> | 26 | <tr> |
| 22 | <td align="center"> | 27 | <td style="text-align: center"> |
| 23 | <a href="http://www.lua.org"> | 28 | <a href="http://www.lua.org"> |
| 24 | <img src="multi.png" alt="Lua" align="middle" border="0" height="120" width="128" /> | 29 | <img src="multi.png" alt="Lua" align="middle" border="0" height="120" width="128" /> |
| 25 | <img src="multi.png" alt="Lua" align="middle" border="0" height="120" width="128" /> | 30 | <img src="multi.png" alt="Lua" align="middle" border="0" height="120" width="128" /> |
| @@ -30,7 +35,7 @@ | |||
| 30 | </td> | 35 | </td> |
| 31 | </tr> | 36 | </tr> |
| 32 | <tr> | 37 | <tr> |
| 33 | <td align="center" valign="top"><h1>Lua Lanes - multithreading in Lua</h1></td> | 38 | <td valign="top"><h1 style="text-align: center">Lua Lanes - multithreading in Lua</h1></td> |
| 34 | </tr> | 39 | </tr> |
| 35 | </tbody></table> | 40 | </tbody></table> |
| 36 | 41 | ||
| @@ -62,18 +67,16 @@ | |||
| 62 | </p> | 67 | </p> |
| 63 | <!-- ... --> | 68 | <!-- ... --> |
| 64 | 69 | ||
| 65 | <font size="-1"> | 70 | <p> |
| 66 | <p> | 71 | <br /> |
| 67 | <br /> | 72 | <i>Copyright © 2007-26 Asko Kauppi, Benoit Germain. All rights reserved.</i> |
| 68 | <i>Copyright © 2007-26 Asko Kauppi, Benoit Germain. All rights reserved.</i> | 73 | <br /> |
| 69 | <br /> | 74 | Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1, 5.2, 5.3, 5.4 and 5.5. |
| 70 | Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1, 5.2, 5.3, 5.4 and 5.5. | 75 | </p> |
| 71 | </p> | 76 | |
| 72 | 77 | <p> | |
| 73 | <p> | 78 | This document was revised on 3-Mar-2026, and applies to version <code>4.0.0</code>. |
| 74 | This document was revised on 26-Feb-2026, and applies to version <tt>4.0.0</tt>. | 79 | </p> |
| 75 | </p> | ||
| 76 | </font> | ||
| 77 | </center> | 80 | </center> |
| 78 | </div> | 81 | </div> |
| 79 | 82 | ||
| @@ -86,7 +89,7 @@ | |||
| 86 | Lua Lanes is a Lua extension library providing the possibility to run multiple Lua states in parallel. It is intended to be used for optimizing performance on multicore CPU's and to study ways to make Lua programs naturally parallel to begin with. | 89 | Lua Lanes is a Lua extension library providing the possibility to run multiple Lua states in parallel. It is intended to be used for optimizing performance on multicore CPU's and to study ways to make Lua programs naturally parallel to begin with. |
| 87 | </p> | 90 | </p> |
| 88 | <p> | 91 | <p> |
| 89 | Lanes is included into your software by the regular <tt>require "lanes"</tt> method. No C side programming is needed; all APIs are Lua side, and most existing extension modules should work seamlessly together with the multiple lanes. | 92 | Lanes is included into your software by the regular <code>require "lanes"</code> method. No C side programming is needed; all APIs are Lua side, and most existing extension modules should work seamlessly together with the multiple lanes. |
| 90 | </p> | 93 | </p> |
| 91 | <p> | 94 | <p> |
| 92 | Lanes should build and run identically with either Lua 5.1 to Lua 5.5, as well as LuaJIT. | 95 | Lanes should build and run identically with either Lua 5.1 to Lua 5.5, as well as LuaJIT. |
| @@ -153,11 +156,11 @@ | |||
| 153 | <h2 id="installing">Building and Installing</h2> | 156 | <h2 id="installing">Building and Installing</h2> |
| 154 | 157 | ||
| 155 | <p> | 158 | <p> |
| 156 | Lua Lanes is implemented in C++20. It is built simply by <tt>make</tt> on the supported platforms (<tt>make-vc</tt> for Visual C++). See <tt>README</tt> for system specific details and limitations. | 159 | Lua Lanes is implemented in C++20. It is built simply by <code>make</code> on the supported platforms (<code>make-vc</code> for Visual C++). See <code>README</code> for system specific details and limitations. |
| 157 | </p> | 160 | </p> |
| 158 | 161 | ||
| 159 | <p> | 162 | <p> |
| 160 | To install Lanes, all you need are the <tt>lanes.lua</tt> and <tt>lanes_core.so|dll</tt> files to be reachable by Lua (see LUA_PATH, LUA_CPATH). | 163 | To install Lanes, all you need are the <code>lanes.lua</code> and <code>lanes_core.so|dll</code> files to be reachable by Lua (see LUA_PATH, LUA_CPATH). |
| 161 | Or use <A HREF="http://www.luarocks.org" TARGET="_blank">Lua Rocks</A> package management. | 164 | Or use <A HREF="http://www.luarocks.org" TARGET="_blank">Lua Rocks</A> package management. |
| 162 | </p> | 165 | </p> |
| 163 | 166 | ||
| @@ -175,76 +178,76 @@ | |||
| 175 | <h2 id="apicheatsheet">API Cheat sheet</h2> | 178 | <h2 id="apicheatsheet">API Cheat sheet</h2> |
| 176 | <ul> | 179 | <ul> |
| 177 | <li> | 180 | <li> |
| 178 | <tt>require "lanes"</tt>: to require Lanes | 181 | <code>require "lanes"</code>: to require Lanes |
| 179 | </li> | 182 | </li> |
| 180 | <li> | 183 | <li> |
| 181 | The <tt>lanes</tt> module | 184 | The <code>lanes</code> module |
| 182 | <ul> | 185 | <ul> |
| 183 | <li><tt>lanes.cancel_error</tt>: a special error value returned from cancelled lanes</li> | 186 | <li><code>lanes.cancel_error</code>: a special error value returned from cancelled lanes</li> |
| 184 | <li><tt>lanes.collectgarbage()</tt>: trigger a GC cycle in all Keeper states</li> | 187 | <li><code>lanes.collectgarbage()</code>: trigger a GC cycle in all Keeper states</li> |
| 185 | <li><tt>lanes.configure()</tt>: configure Lanes</li> | 188 | <li><code>lanes.configure()</code>: configure Lanes</li> |
| 186 | <li><tt>lanes.coro()</tt>: start a coroutine-like lane</li> | 189 | <li><code>lanes.coro()</code>: start a coroutine-like lane</li> |
| 187 | <li><tt>lanes.finally()</tt>: install a function called on Lanes shutdown</li> | 190 | <li><code>lanes.finally()</code>: install a function called on Lanes shutdown</li> |
| 188 | <li><tt>lanes.gen()</tt>: start a lane as a regular function</li> | 191 | <li><code>lanes.gen()</code>: start a lane as a regular function</li> |
| 189 | <li><tt>lanes.genatomic()</tt>: obtain an atomic counter</li> | 192 | <li><code>lanes.genatomic()</code>: obtain an atomic counter</li> |
| 190 | <li><tt>lanes.genlock()</tt>: obtain an atomic-like data stack</li> | 193 | <li><code>lanes.genlock()</code>: obtain an atomic-like data stack</li> |
| 191 | <li><tt>lanes.linda()</tt>: create a <a href="#lindas">linda</a></li> | 194 | <li><code>lanes.linda()</code>: create a <a href="#lindas">linda</a></li> |
| 192 | <li><tt>lanes.nameof()</tt>: find where a value exists</li> | 195 | <li><code>lanes.nameof()</code>: find where a value exists</li> |
| 193 | <li><tt>lanes.null</tt>: a light userdata used to represent <tt>nil</tt> in data transfers</li> | 196 | <li><code>lanes.null</code>: a light userdata used to represent <code>nil</code> in data transfers</li> |
| 194 | <li><tt>lanes.thread_priority_range()</tt>: obtain the valid range of thread priorities</li> | 197 | <li><code>lanes.thread_priority_range()</code>: obtain the valid range of thread priorities</li> |
| 195 | <li><tt>lanes.now_secs()</tt>: obtain the current clock value</li> | 198 | <li><code>lanes.now_secs()</code>: obtain the current clock value</li> |
| 196 | <li><tt>lanes.register()</tt>: scan modules so that functions using them can be transferred</li> | 199 | <li><code>lanes.register()</code>: scan modules so that functions using them can be transferred</li> |
| 197 | <li><tt>lanes.set_thread_priority()</tt>: change thread priority</li> | 200 | <li><code>lanes.set_thread_priority()</code>: change thread priority</li> |
| 198 | <li><tt>lanes.set_thread_affinity()</tt>: change thread affinity</li> | 201 | <li><code>lanes.set_thread_affinity()</code>: change thread affinity</li> |
| 199 | <li><tt>lanes.threads()</tt>: obtain a list of all lanes</li> | 202 | <li><code>lanes.threads()</code>: obtain a list of all lanes</li> |
| 200 | <li><tt>lanes.sleep()</tt>: sleep for a given duration</li> | 203 | <li><code>lanes.sleep()</code>: sleep for a given duration</li> |
| 201 | <li><tt>lanes.timer()</tt>: start a timer</li> | 204 | <li><code>lanes.timer()</code>: start a timer</li> |
| 202 | <li><tt>lanes.timer_lane</tt>: the lane that manages timers</li> | 205 | <li><code>lanes.timer_lane</code>: the lane that manages timers</li> |
| 203 | <li><tt>lanes.timers()</tt>: list active timers</li> | 206 | <li><code>lanes.timers()</code>: list active timers</li> |
| 204 | </ul> | 207 | </ul> |
| 205 | </li> | 208 | </li> |
| 206 | <li> | 209 | <li> |
| 207 | Given some lane handle <tt>lane_h</tt> | 210 | Given some lane handle <code>lane_h</code> |
| 208 | <ul> | 211 | <ul> |
| 209 | <li><tt>lane_h[]</tt>: wait for, and read the values returned by the lane</li> | 212 | <li><code>lane_h[]</code>: wait for, and read the values returned by the lane</li> |
| 210 | <li><tt>lane_h:cancel()</tt>: request the lane to stop running</li> | 213 | <li><code>lane_h:cancel()</code>: request the lane to stop running</li> |
| 211 | <li><tt>lane_h.error_trace_level</tt>: current setting of error logging level</li> | 214 | <li><code>lane_h.error_trace_level</code>: current setting of error logging level</li> |
| 212 | <li><tt>lane_h:get_threadname()</tt>: read the thread name</li> | 215 | <li><code>lane_h:get_threadname()</code>: read the thread name</li> |
| 213 | <li><tt>lane_h:join()</tt>: wait for the lane to close, reading the returned values</li> | 216 | <li><code>lane_h:join()</code>: wait for the lane to close, reading the returned values</li> |
| 214 | <li><tt>lane_h:resume()</tt>: resume a coroutine Lane</li> | 217 | <li><code>lane_h:resume()</code>: resume a coroutine Lane</li> |
| 215 | <li><tt>lane_h.status</tt>: current status of the lane</li> | 218 | <li><code>lane_h.status</code>: current status of the lane</li> |
| 216 | </ul> | 219 | </ul> |
| 217 | </li> | 220 | </li> |
| 218 | <li> | 221 | <li> |
| 219 | Inside the lane | 222 | Inside the lane |
| 220 | <ul> | 223 | <ul> |
| 221 | <li><tt>cancel_test()</tt>: check for <a href="#cancelling">cancellation</a> requests</li> | 224 | <li><code>cancel_test()</code>: check for <a href="#cancelling">cancellation</a> requests</li> |
| 222 | <li><tt>lane_threadname()</tt>: read or change the name of the thread</li> | 225 | <li><code>lane_threadname()</code>: read or change the name of the thread</li> |
| 223 | <li><tt>set_finalizer()</tt>: install a function called when the lane exits</li> | 226 | <li><code>set_finalizer()</code>: install a function called when the lane exits</li> |
| 224 | </ul> | 227 | </ul> |
| 225 | </li> | 228 | </li> |
| 226 | <li> | 229 | <li> |
| 227 | Given some <a href="#lindas">linda</a> <tt>l</tt> | 230 | Given some <a href="#lindas">linda</a> <code>l</code> |
| 228 | <ul> | 231 | <ul> |
| 229 | <li><tt>l:cancel()</tt>: mark a <a href="#lindas">linda</a> for <a href="#cancelling">cancellation</a></li> | 232 | <li><code>l:cancel()</code>: mark a <a href="#lindas">linda</a> for <a href="#cancelling">cancellation</a></li> |
| 230 | <li><tt>l:collectgarbage()</tt>: trigger a GC cycle in the <a href="#lindas">linda</a>'s Keeper state</li> | 233 | <li><code>l:collectgarbage()</code>: trigger a GC cycle in the <a href="#lindas">linda</a>'s Keeper state</li> |
| 231 | <li><tt>l:deep()</tt>: obtain a light userdata uniquely representing the <a href="#lindas">linda</a></li> | 234 | <li><code>l:deep()</code>: obtain a light userdata uniquely representing the <a href="#lindas">linda</a></li> |
| 232 | <li><tt>l:dump()</tt>: have information about slot contents</li> | 235 | <li><code>l:dump()</code>: have information about slot contents</li> |
| 233 | <li><tt>l:count()</tt>: obtain a count of data items in slots</li> | 236 | <li><code>l:count()</code>: obtain a count of data items in slots</li> |
| 234 | <li><tt>l:get()</tt>: read data without consuming it</li> | 237 | <li><code>l:get()</code>: read data without consuming it</li> |
| 235 | <li><tt>l:limit()</tt>: cap the amount of transiting data</li> | 238 | <li><code>l:limit()</code>: cap the amount of transiting data</li> |
| 236 | <li><tt>l:receive()</tt>: read one item of data from multiple slots</li> | 239 | <li><code>l:receive()</code>: read one item of data from multiple slots</li> |
| 237 | <li><tt>l:receive_batched()</tt>: read several item of data from a single slot</li> | 240 | <li><code>l:receive_batched()</code>: read several item of data from a single slot</li> |
| 238 | <li><tt>l:restrict()</tt>: place a restraint on the operations that can be done on a slot</li> | 241 | <li><code>l:restrict()</code>: place a restraint on the operations that can be done on a slot</li> |
| 239 | <li><tt>l:send()</tt>: append data</li> | 242 | <li><code>l:send()</code>: append data</li> |
| 240 | <li><tt>l:set()</tt>: replace the data</li> | 243 | <li><code>l:set()</code>: replace the data</li> |
| 241 | <li><tt>l:wake()</tt>: manually wake blocking calls</li> | 244 | <li><code>l:wake()</code>: manually wake blocking calls</li> |
| 242 | </ul> | 245 | </ul> |
| 243 | </li> | 246 | </li> |
| 244 | <li> | 247 | <li> |
| 245 | embedding | 248 | embedding |
| 246 | <ul> | 249 | <ul> |
| 247 | <li><tt>luaopen_lanes_embedded()</tt>: manually initialize Lanes</li> | 250 | <li><code>luaopen_lanes_embedded()</code>: manually initialize Lanes</li> |
| 248 | </ul> | 251 | </ul> |
| 249 | </li> | 252 | </li> |
| 250 | </ul> | 253 | </ul> |
| @@ -264,9 +267,9 @@ | |||
| 264 | </tr> | 267 | </tr> |
| 265 | </table> | 268 | </table> |
| 266 | <p> | 269 | <p> |
| 267 | <tt>luaopen_lanes_embedded</tt> leaves the module table on the stack. <a href="#initialization"><tt>lanes.configure()</tt></a> must still be called in order to use Lanes. | 270 | <code>luaopen_lanes_embedded</code> leaves the module table on the stack. <a href="#initialization"><code>lanes.configure()</code></a> must still be called in order to use Lanes. |
| 268 | <br /> | 271 | <br /> |
| 269 | If <tt>_luaopen_lanes</tt> is <tt>nullptr</tt>, a default loader will simply attempt the equivalent of <tt>luaL_dofile(L, "lanes.lua")</tt>. | 272 | If <code>_luaopen_lanes</code> is <code>nullptr</code>, a default loader will simply attempt the equivalent of <code>luaL_dofile(L, "lanes.lua")</code>. |
| 270 | </p> | 273 | </p> |
| 271 | 274 | ||
| 272 | <p> | 275 | <p> |
| @@ -277,33 +280,34 @@ | |||
| 277 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> | 280 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> |
| 278 | <tr> | 281 | <tr> |
| 279 | <td> | 282 | <td> |
| 280 | <pre> #include "lanes.hpp"</pre> | 283 | <pre> |
| 281 | <br /> | 284 | #include "lanes.hpp" |
| 282 | <pre> int load_lanes_lua(lua_State* L)</pre> | 285 | |
| 283 | <pre> {</pre> | 286 | int load_lanes_lua(lua_State* L) |
| 284 | <pre> // retrieve lanes.lua from wherever it is stored and return the result of its execution</pre> | 287 | { |
| 285 | <pre> // trivial example 1:</pre> | 288 | // retrieve lanes.lua from wherever it is stored and return the result of its execution |
| 286 | <pre> luaL_dofile(L, "lanes.lua");</pre> | 289 | // trivial example 1: |
| 287 | <br /> | 290 | luaL_dofile(L, "lanes.lua"); |
| 288 | <pre> // trivial example 2:</pre> | 291 | |
| 289 | <pre> luaL_dostring(L, bin2c_lanes_lua);</pre> | 292 | // trivial example 2: |
| 290 | <pre> }</pre> | 293 | luaL_dostring(L, bin2c_lanes_lua); |
| 291 | <br /> | 294 | } |
| 292 | <pre> void embed_lanes(lua_State* L)</pre> | 295 | |
| 293 | <pre> {</pre> | 296 | void embed_lanes(lua_State* L) |
| 294 | <pre> // we need base libraries for Lanes for work</pre> | 297 | { |
| 295 | <pre> luaL_openlibs(L);</pre> | 298 | // we need base libraries for Lanes for work |
| 296 | <pre> ...</pre> | 299 | luaL_openlibs(L); |
| 297 | <pre> // will attempt luaL_dofile(L, "lanes.lua");</pre> | 300 | ... |
| 298 | <pre> luaopen_lanes_embedded(L, nullptr);</pre> | 301 | // will attempt luaL_dofile(L, "lanes.lua"); |
| 299 | <pre> lua_pop(L, 1);</pre> | 302 | luaopen_lanes_embedded(L, nullptr); |
| 300 | <pre> // another example with a custom loader</pre> | 303 | lua_pop(L, 1); |
| 301 | <pre> luaopen_lanes_embedded(L, load_lanes_lua);</pre> | 304 | // another example with a custom loader |
| 302 | <pre> lua_pop(L, 1);</pre> | 305 | luaopen_lanes_embedded(L, load_lanes_lua); |
| 303 | <br /> | 306 | lua_pop(L, 1); |
| 304 | <pre> // a little test to make sure things work as expected</pre> | 307 | |
| 305 | <pre> luaL_dostring(L, "local lanes = require 'lanes'.configure{with_timers = false}; local l = lanes.linda()");</pre> | 308 | // a little test to make sure things work as expected |
| 306 | <pre> }</pre> | 309 | luaL_dostring(L, "local lanes = require 'lanes'.configure{with_timers = false}; local l = lanes.linda()"); |
| 310 | } | ||
| 307 | </td> | 311 | </td> |
| 308 | </tr> | 312 | </tr> |
| 309 | </table> | 313 | </table> |
| @@ -327,17 +331,17 @@ | |||
| 327 | </table> | 331 | </table> |
| 328 | 332 | ||
| 329 | <p> | 333 | <p> |
| 330 | Requiring the module follows Lua 5.2+ rules: the module is not available under the global name "lanes", but has to be accessed through <tt>require</tt>'s return value.<br /> | 334 | Requiring the module follows Lua 5.2+ rules: the module is not available under the global name "lanes", but has to be accessed through <code>require</code>'s return value.<br /> |
| 331 | Lanes needs <tt>"base"</tt>, <tt>"string"</tt> and <tt>"table"</tt> to be initialized beforehand (plus <tt>"jit"</tt> for LuaJIT). | 335 | Lanes needs <code>"base"</code>, <code>"string"</code> and <code>"table"</code> to be initialized beforehand (plus <code>"jit"</code> for LuaJIT). |
| 332 | </p> | 336 | </p> |
| 333 | <p> | 337 | <p> |
| 334 | After lanes is required, it is recommended to call <tt>lanes.configure()</tt>, which is the only function exposed by the module at this point. Calling <tt>lanes.configure()</tt> will perform one-time initializations and make the rest of the API available.<br /> | 338 | After lanes is required, it is recommended to call <code>lanes.configure()</code>, which is the only function exposed by the module at this point. Calling <code>lanes.configure()</code> will perform one-time initializations and make the rest of the API available.<br /> |
| 335 | If <tt>lanes.configure()</tt> is not called before starting to use Lanes, it will be called automatically for you with default settings.<br /> | 339 | If <code>lanes.configure()</code> is not called before starting to use Lanes, it will be called automatically for you with default settings.<br /> |
| 336 | Only the first occurence of <tt>require "lanes"</tt> must be followed by a call to <tt>lanes.configure()</tt>. From this point, a simple <tt>require "lanes"</tt> will be enough wherever you need to require lanes again.<br /> | 340 | Only the first occurence of <code>require "lanes"</code> must be followed by a call to <code>lanes.configure()</code>. From this point, a simple <code>require "lanes"</code> will be enough wherever you need to require lanes again.<br /> |
| 337 | After being called, <tt>lanes.configure()</tt> itself is replaced by another function that does nothing with the argument it receives, in case it happens to be called again. | 341 | After being called, <code>lanes.configure()</code> itself is replaced by another function that does nothing with the argument it receives, in case it happens to be called again. |
| 338 | </p> | 342 | </p> |
| 339 | <p> | 343 | <p> |
| 340 | Also, once Lanes is initialized, <tt>require()</tt> is replaced by another one that wraps it inside a mutex, both in the main state and in all created lanes. This prevents multiple thread-unsafe module initializations from several lanes to occur simultaneously. | 344 | Also, once Lanes is initialized, <code>require()</code> is replaced by another one that wraps it inside a mutex, both in the main state and in all created lanes. This prevents multiple thread-unsafe module initializations from several lanes to occur simultaneously. |
| 341 | It remains to be seen whether this is actually useful or not: If a module is already threadsafe, protecting its initialization isn't useful. And if it is not, any parallel operation may crash without Lanes being able to do anything about it. | 345 | It remains to be seen whether this is actually useful or not: If a module is already threadsafe, protecting its initialization isn't useful. And if it is not, any parallel operation may crash without Lanes being able to do anything about it. |
| 342 | </p> | 346 | </p> |
| 343 | 347 | ||
| @@ -352,11 +356,11 @@ | |||
| 352 | </p> | 356 | </p> |
| 353 | 357 | ||
| 354 | <p> | 358 | <p> |
| 355 | <tt>lanes.configure</tt> accepts an optional table as sole argument. | 359 | <code>lanes.configure</code> accepts an optional table as sole argument. |
| 356 | <table border="1" cellpadding="10" style="width:100%"> | 360 | <table border="1" cellpadding="10" style="width:100%" class="striped"> |
| 357 | <tr> | 361 | <tr> |
| 358 | <th style="width:15%">name</th> | 362 | <th style="width:20%">name</th> |
| 359 | <th style="width:15%">value</th> | 363 | <th>values</th> |
| 360 | <th style="width:70%">definition</th> | 364 | <th style="width:70%">definition</th> |
| 361 | </tr> | 365 | </tr> |
| 362 | 366 | ||
| @@ -365,26 +369,28 @@ | |||
| 365 | <code>.allocator</code> | 369 | <code>.allocator</code> |
| 366 | </td> | 370 | </td> |
| 367 | <td> | 371 | <td> |
| 368 | <tt>nil</tt>/<tt>"protected"</tt>/function | 372 | <code>nil</code><br /> |
| 373 | <code>"protected"</code><br /> | ||
| 374 | function | ||
| 369 | </td> | 375 | </td> |
| 370 | <td> | 376 | <td> |
| 371 | If <tt>nil</tt>, Lua states are created with <tt>lua_newstate()</tt> and reuse the allocator from the master state.<br /> | 377 | If <code>nil</code>, Lua states are created with <code>lua_newstate()</code> and reuse the allocator from the master state.<br /> |
| 372 | If <tt>"protected"</tt>, The default allocator obtained from <tt>lua_getallocf()</tt> in the master state is wrapped inside a critical section and used in all newly created states.<br /> | 378 | If <code>"protected"</code>, The default allocator obtained from <code>lua_getallocf()</code> in the master state is wrapped inside a critical section and used in all newly created states.<br /> |
| 373 | If a <tt>function</tt>, this function is called prior to creating the state, with a single string argument, either <tt>"internal"</tt>, <tt>"keeper"</tt> or <tt>"lane"</tt>. It should return a full userdata created as follows: | 379 | If a <code>function</code>, this function is called prior to creating the state, with a single string argument, either <code>"internal"</code>, <code>"keeper"</code> or <code>"lane"</code>. It should return a full userdata created as follows: |
| 374 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> | 380 | <table border="1" bgcolor="#E0E0FF" cellpadding="10"> |
| 375 | <tr> | 381 | <tr> |
| 376 | <td> | 382 | <td> |
| 377 | <pre> | 383 | <pre> |
| 378 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { | 384 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { |
| 379 | lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} }; | 385 | lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} }; |
| 380 | // populate _def->allocF and _def->allocUD here | 386 | // populate _def->allocF and _def->allocUD here |
| 381 | return 1; | 387 | return 1; |
| 382 | }; | 388 | }; |
| 383 | </pre> | 389 | </pre> |
| 384 | </td> | 390 | </td> |
| 385 | </tr> | 391 | </tr> |
| 386 | </table> | 392 | </table> |
| 387 | The contents will be used to create the state with <tt>lua_newstate(allocF, allocUD)</tt>. | 393 | The contents will be used to create the state with <code>lua_newstate(allocF, allocUD)</code>. |
| 388 | This option is mostly useful for embedders that want to provide different allocators to each lane, for example to have each one work in a different memory pool thus preventing the need for the allocator itself to be threadsafe. | 394 | This option is mostly useful for embedders that want to provide different allocators to each lane, for example to have each one work in a different memory pool thus preventing the need for the allocator itself to be threadsafe. |
| 389 | </td> | 395 | </td> |
| 390 | </tr> | 396 | </tr> |
| @@ -394,10 +400,12 @@ | |||
| 394 | <code>.convert_fallback</code> | 400 | <code>.convert_fallback</code> |
| 395 | </td> | 401 | </td> |
| 396 | <td> | 402 | <td> |
| 397 | <tt>nil</tt>, <tt>lanes.null</tt> or <tt>'decay'</tt> | 403 | <code>nil</code><br /> |
| 404 | <code>lanes.null</code><br /> | ||
| 405 | <code>'decay'</code> | ||
| 398 | </td> | 406 | </td> |
| 399 | <td> | 407 | <td> |
| 400 | Same as <tt>__lanesconvert</tt> (see <a href="#other">Limitations on data passing</a>), but cannot be a function, because this would have to be transferred to all newly created lanes. | 408 | Same as <code>__lanesconvert</code> (see <a href="#other">Limitations on data passing</a>), but cannot be a function, because this would have to be transferred to all newly created lanes. |
| 401 | </td> | 409 | </td> |
| 402 | </tr> | 410 | </tr> |
| 403 | 411 | ||
| @@ -418,12 +426,13 @@ | |||
| 418 | <code>.internal_allocator</code> | 426 | <code>.internal_allocator</code> |
| 419 | </td> | 427 | </td> |
| 420 | <td> | 428 | <td> |
| 421 | <tt>"libc"</tt>/<tt>"allocator"</tt> | 429 | <code>"libc"</code><br /> |
| 430 | <code>"allocator"</code> | ||
| 422 | </td> | 431 | </td> |
| 423 | <td> | 432 | <td> |
| 424 | Controls which allocator is used for Lanes internal allocations (for <a href="#keepers">Keeper state</a>, <a href="#lindas">linda</a> and lane management). | 433 | Controls which allocator is used for Lanes internal allocations (for <a href="#keepers">Keeper state</a>, <a href="#lindas">linda</a> and lane management). |
| 425 | If <tt>"libc"</tt>, Lanes uses <tt>realloc</tt> and <tt>free</tt>.<br /> | 434 | If <code>"libc"</code>, Lanes uses <code>realloc</code> and <code>free</code>.<br /> |
| 426 | If <tt>"allocator"</tt>, Lanes uses whatever was obtained from the <tt>"allocator"</tt> setting.<br /> | 435 | If <code>"allocator"</code>, Lanes uses whatever was obtained from the <code>"allocator"</code> setting.<br /> |
| 427 | 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). | 436 | 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). |
| 428 | </td> | 437 | </td> |
| 429 | </tr> | 438 | </tr> |
| @@ -436,7 +445,7 @@ | |||
| 436 | <td> | 445 | <td> |
| 437 | If <0, GC runs automatically. This is the default.<br /> | 446 | If <0, GC runs automatically. This is the default.<br /> |
| 438 | If 0, GC runs after *every* <a href="#keepers">Keeper</a> operation.<br /> | 447 | If 0, GC runs after *every* <a href="#keepers">Keeper</a> operation.<br /> |
| 439 | If >0, <a href="#keepers">Keeper states</a> run GC manually with <tt>lua_gc(LUA_GCCOLLECT)</tt> whenever memory usage reported by <tt>lua_gc(LUA_GCCOUNT)</tt> reaches this threshold. | 448 | If >0, <a href="#keepers">Keeper states</a> run GC manually with <code>lua_gc(LUA_GCCOLLECT)</code> whenever memory usage reported by <code>lua_gc(LUA_GCCOUNT)</code> reaches this threshold. |
| 440 | Check is made after every operation (see <a href="#lindas">below</a>). If memory usage remains above threshold after the GC cycle, an error is raised. | 449 | Check is made after every operation (see <a href="#lindas">below</a>). If memory usage remains above threshold after the GC cycle, an error is raised. |
| 441 | </td> | 450 | </td> |
| 442 | </tr> | 451 | </tr> |
| @@ -446,11 +455,11 @@ | |||
| 446 | <code>.linda_wake_period</code> | 455 | <code>.linda_wake_period</code> |
| 447 | </td> | 456 | </td> |
| 448 | <td> | 457 | <td> |
| 449 | number > 0 | 458 | number > 0 |
| 450 | </td> | 459 | </td> |
| 451 | <td> | 460 | <td> |
| 452 | Sets the default period in seconds a <a href="#lindas">linda</a> will wake by itself during blocked operations. Default is never.<br /> | 461 | Sets the default period in seconds a <a href="#lindas">linda</a> will wake by itself during blocked operations. Default is never.<br /> |
| 453 | When a <a href="#lindas">linda</a> enters a blocking call (<tt>send()</tt>, <tt>receive()</tt>, <tt>receive_batched()</tt>, <tt>sleep()</tt>), it normally sleeps either until the operation completes | 462 | When a <a href="#lindas">linda</a> enters a blocking call (<code>send()</code>, <code>receive()</code>, <code>receive_batched()</code>, <code>sleep()</code>), it normally sleeps either until the operation completes |
| 454 | or the specified timeout expires. With this setting, the default behavior can be changed to wake periodically. This can help for example with timing issues where a lane is signalled | 463 | or the specified timeout expires. With this setting, the default behavior can be changed to wake periodically. This can help for example with timing issues where a lane is signalled |
| 455 | for <a href="#cancelling">cancellation</a>, but a <a href="#lindas">linda</a> inside the lane was in the middle of processing an operation but did not actually start the wait. This can result in the signal to be ignored, thus | 464 | for <a href="#cancelling">cancellation</a>, but a <a href="#lindas">linda</a> inside the lane was in the middle of processing an operation but did not actually start the wait. This can result in the signal to be ignored, thus |
| 456 | causing the <a href="#lindas">linda</a> to wait out the full operation timeout before <a href="#cancelling">cancellation</a> is processed. | 465 | causing the <a href="#lindas">linda</a> to wait out the full operation timeout before <a href="#cancelling">cancellation</a> is processed. |
| @@ -461,10 +470,10 @@ | |||
| 461 | <td id="nb_user_keepers"> | 470 | <td id="nb_user_keepers"> |
| 462 | <code>.nb_user_keepers</code> | 471 | <code>.nb_user_keepers</code> |
| 463 | </td> | 472 | </td> |
| 464 | <td>integer in [0,100]</td> | 473 | <td>0 ≤ number ≤ 100</td> |
| 465 | <td> | 474 | <td> |
| 466 | 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 /> | 475 | 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 <code>0</code>.<br /> |
| 467 | 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 /> | 476 | Lanes always creates at least one keeper state (of group <code>0</code> for the internal timer <a href="#lindas">linda</a>. If <code>nb_user_keepers</code> is <code>0</code>, the other lindas you create will share this keeper by necessity.<br /> |
| 468 | 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. | 477 | 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. |
| 469 | </td> | 478 | </td> |
| 470 | </tr> | 479 | </tr> |
| @@ -474,19 +483,20 @@ | |||
| 474 | <code>.on_state_create</code> | 483 | <code>.on_state_create</code> |
| 475 | </td> | 484 | </td> |
| 476 | <td> | 485 | <td> |
| 477 | <tt>nil</tt>/function | 486 | <code>nil</code><br /> |
| 487 | function | ||
| 478 | </td> | 488 | </td> |
| 479 | <td> | 489 | <td> |
| 480 | If provided, will be called in every created Lua state right after initializing the base libraries, with a single string argument, either <tt>"lane"</tt> or <tt>"keeper"</tt>.<br /> | 490 | If provided, will be called in every created Lua state right after initializing the base libraries, with a single string argument, either <code>"lane"</code> or <code>"keeper"</code>.<br /> |
| 481 | If it is a C function, a C closure will be reconstructed in the created state from the C pointer. Lanes will raise an error if the function has upvalues.<br /> | 491 | If it is a C function, a C closure will be reconstructed in the created state from the C pointer. Lanes will raise an error if the function has upvalues.<br /> |
| 482 | If it is a Lua function, it will be transfered normally before the call.<br /> | 492 | If it is a Lua function, it will be transfered normally before the call.<br /> |
| 483 | Keeper states will call it as well, but only if it is a C function (<a href="#keepers">Keeper states</a> are not able to execute any user Lua code).<br /> | 493 | Keeper states will call it as well, but only if it is a C function (<a href="#keepers">Keeper states</a> are not able to execute any user Lua code).<br /> |
| 484 | Typical usage is twofold: | 494 | Typical usage is twofold: |
| 485 | <ul> | 495 | <ul> |
| 486 | <li>Tweak <tt>package.loaders</tt></li> | 496 | <li>Tweak <code>package.loaders</code></li> |
| 487 | <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li> | 497 | <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li> |
| 488 | </ul> | 498 | </ul> |
| 489 | That way, all changes in the state can be properly taken into account when building the function lookup database. Default is <tt>nil</tt>.<br /> | 499 | That way, all changes in the state can be properly taken into account when building the function lookup database. Default is <code>nil</code>.<br /> |
| 490 | </td> | 500 | </td> |
| 491 | </tr> | 501 | </tr> |
| 492 | 502 | ||
| @@ -498,10 +508,10 @@ | |||
| 498 | number >= 0 | 508 | number >= 0 |
| 499 | </td> | 509 | </td> |
| 500 | <td> | 510 | <td> |
| 501 | Sets the duration in seconds Lanes will wait for graceful termination of running lanes at application shutdown. Default is <tt>0.25</tt>.<br /> | 511 | Sets the duration in seconds Lanes will wait for graceful termination of running lanes at application shutdown. Default is <code>0.25</code>.<br /> |
| 502 | Lanes signals all lanes for <a href="#cancelling">cancellation</a> with <tt>"soft"</tt>, <tt>"hard"</tt>, and <tt>"all"</tt> modes, in that order. Each attempt has <tt>shutdown_timeout</tt> seconds to succeed before the next one.<br /> | 512 | Lanes signals all lanes for <a href="#cancelling">cancellation</a> with <code>"soft"</code>, <code>"hard"</code>, and <code>"all"</code> modes, in that order. Each attempt has <code>shutdown_timeout</code> seconds to succeed before the next one.<br /> |
| 503 | Then there is a last chance at cleanup with <a href="#finally"><tt>lanes.finally()</tt></a>. If some lanes are still running after that point, shutdown will either freeze or throw. It is YOUR responsibility to cleanup properly after yourself. | 513 | Then there is a last chance at cleanup with <a href="#finally"><code>lanes.finally()</code></a>. If some lanes are still running after that point, shutdown will either freeze or throw. It is YOUR responsibility to cleanup properly after yourself. |
| 504 | IMPORTANT: If there are still running lanes at shutdown, an error is raised, which will be propagated by Lua to the handler installed by <tt>lua_setwarnf</tt>. If the finalizer returned a value, this will be used as the error message.<br /> | 514 | IMPORTANT: If there are still running lanes at shutdown, an error is raised, which will be propagated by Lua to the handler installed by <code>lua_setwarnf</code>. If the finalizer returned a value, this will be used as the error message.<br /> |
| 505 | LANES SHUTDOWN WILL NOT BE COMPLETE IN THAT CASE, AND THE SUBSEQUENT CONSEQUENCES ARE UNDEFINED! | 515 | LANES SHUTDOWN WILL NOT BE COMPLETE IN THAT CASE, AND THE SUBSEQUENT CONSEQUENCES ARE UNDEFINED! |
| 506 | </td> | 516 | </td> |
| 507 | </tr> | 517 | </tr> |
| @@ -511,10 +521,10 @@ | |||
| 511 | <code>.strip_functions</code> | 521 | <code>.strip_functions</code> |
| 512 | </td> | 522 | </td> |
| 513 | <td> | 523 | <td> |
| 514 | <tt>nil</tt>/<tt>boolean</tt> | 524 | <code>nil</code>/<code>boolean</code> |
| 515 | </td> | 525 | </td> |
| 516 | <td> | 526 | <td> |
| 517 | Controls function bytecode stripping when dumping them for lane transfer. Choose between faster copies or more debug info. Default is <tt>true</tt>. | 527 | Controls function bytecode stripping when dumping them for lane transfer. Choose between faster copies or more debug info. Default is <code>true</code>. |
| 518 | </td> | 528 | </td> |
| 519 | </tr> | 529 | </tr> |
| 520 | <tr valign=top> | 530 | <tr valign=top> |
| @@ -522,11 +532,11 @@ | |||
| 522 | <code>.track_lanes</code> | 532 | <code>.track_lanes</code> |
| 523 | </td> | 533 | </td> |
| 524 | <td> | 534 | <td> |
| 525 | <tt>nil</tt>/<tt>boolean</tt> | 535 | <code>nil</code>/<code>boolean</code> |
| 526 | </td> | 536 | </td> |
| 527 | <td> | 537 | <td> |
| 528 | Any non-<tt>nil|false</tt> value instructs Lanes keeps track of all lanes, so that <a href="#tracking"><tt>lanes.threads()</tt></a> can list them. If <tt>false</tt>, <tt>lanes.threads()</tt> will raise an error when called. | 538 | Any non-<code>nil|false</code> value instructs Lanes keeps track of all lanes, so that <a href="#tracking"><code>lanes.threads()</code></a> can list them. If <code>false</code>, <code>lanes.threads()</code> will raise an error when called. |
| 529 | Default is <tt>false</tt>. | 539 | Default is <code>false</code>. |
| 530 | </td> | 540 | </td> |
| 531 | </tr> | 541 | </tr> |
| 532 | 542 | ||
| @@ -535,11 +545,11 @@ | |||
| 535 | <code>.verbose_errors</code> | 545 | <code>.verbose_errors</code> |
| 536 | </td> | 546 | </td> |
| 537 | <td> | 547 | <td> |
| 538 | <tt>nil</tt>/<tt>boolean</tt> | 548 | <code>nil</code>/<code>boolean</code> |
| 539 | </td> | 549 | </td> |
| 540 | <td> | 550 | <td> |
| 541 | If equal to <tt>true</tt>, Lanes will collect more information when transfering stuff across Lua states to help identify errors (with a cost). | 551 | If equal to <code>true</code>, Lanes will collect more information when transfering stuff across Lua states to help identify errors (with a cost). |
| 542 | Default is <tt>false</tt>. | 552 | Default is <code>false</code>. |
| 543 | </td> | 553 | </td> |
| 544 | </tr> | 554 | </tr> |
| 545 | 555 | ||
| @@ -548,11 +558,11 @@ | |||
| 548 | <code>.with_timers</code> | 558 | <code>.with_timers</code> |
| 549 | </td> | 559 | </td> |
| 550 | <td> | 560 | <td> |
| 551 | <tt>nil</tt>/<tt>boolean</tt> | 561 | <code>nil</code>/<code>boolean</code> |
| 552 | </td> | 562 | </td> |
| 553 | <td> | 563 | <td> |
| 554 | If equal to <tt>false</tt> or <tt>nil</tt>, Lanes doesn't start the timer service, and the associated API will be absent from the interface (see below). | 564 | If equal to <code>false</code> or <code>nil</code>, Lanes doesn't start the timer service, and the associated API will be absent from the interface (see below). |
| 555 | Default is <tt>false</tt>. | 565 | Default is <code>false</code>. |
| 556 | </td> | 566 | </td> |
| 557 | </tr> | 567 | </tr> |
| 558 | </table> | 568 | </table> |
| @@ -561,23 +571,25 @@ | |||
| 561 | <p> | 571 | <p> |
| 562 | Once Lanes is configured, one should register with Lanes the modules exporting functions/userdata that will be transferred either during lane generation or through <a href="#lindas">lindas</a>. | 572 | Once Lanes is configured, one should register with Lanes the modules exporting functions/userdata that will be transferred either during lane generation or through <a href="#lindas">lindas</a>. |
| 563 | <br /> | 573 | <br /> |
| 564 | Use <tt>lanes.require()</tt> for this purpose. This will call the original <tt>require()</tt>, then add the result to the lookup databases. | 574 | Use <code>lanes.require()</code> for this purpose. This will call the original <code>require()</code>, then add the result to the lookup databases. |
| 565 | <br /> | 575 | <br /> |
| 566 | It is also possible to register a given module <i>a posteriori</i> with <tt>lanes.register()</tt>. This function will raise an error if the registered module is not a function, table, or full userdata.<br /> | 576 | It is also possible to register a given module <i>a posteriori</i> with <code>lanes.register()</code>. This function will raise an error if the registered module is not a function, table, or full userdata.<br /> |
| 567 | Embedders can call the equivalent function <tt>lanes_register()</tt> from the C side, through <tt>lua_call()</tt> or similar. | 577 | Embedders can call the equivalent function <code>lanes_register()</code> from the C side, through <code>lua_call()</code> or similar. |
| 568 | </p> | 578 | </p> |
| 569 | 579 | ||
| 570 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> | 580 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> |
| 571 | <tr> | 581 | <tr> |
| 572 | <td> | 582 | <td> |
| 573 | <pre> local m = lanes.require "modname"</pre> | 583 | <pre> |
| 574 | <pre> lanes.register("modname", module)</pre> | 584 | local m = lanes.require "modname" |
| 585 | lanes.register("modname", module) | ||
| 586 | </pre> | ||
| 575 | </td> | 587 | </td> |
| 576 | </tr> | 588 | </tr> |
| 577 | </table> | 589 | </table> |
| 578 | 590 | ||
| 579 | <p id="collectgarbage"> | 591 | <p id="collectgarbage"> |
| 580 | A full GC cycle can be triggered on all keeper states with <tt>lanes.collectgarbage()</tt>. This can force the collection of stale storage data for a collected Linda. | 592 | A full GC cycle can be triggered on all keeper states with <code>lanes.collectgarbage()</code>. This can force the collection of stale storage data for a collected Linda. |
| 581 | </p> | 593 | </p> |
| 582 | 594 | ||
| 583 | <p> | 595 | <p> |
| @@ -606,11 +618,11 @@ | |||
| 606 | 618 | ||
| 607 | <p> | 619 | <p> |
| 608 | 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 /> | 620 | 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 /> |
| 609 | Only the last registered finalizer is kept. It can be cleared by passing <tt>nil</tt> or nothing.<br /> | 621 | Only the last registered finalizer is kept. It can be cleared by passing <code>nil</code> or nothing.<br /> |
| 610 | 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 /> | 622 | The finalizer is called unprotected from inside <code>__gc</code> metamethod of Lanes's Universe. Therefore, if your finalizer raises an error, Lua rules regarding errors in finalizers apply normally.<br /> |
| 611 | 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 /> | 623 | The installed function is called after all free-running lanes got a chance to terminate (see <a href="#shutdown_timeout"><code>shutdown_timeout</code></a>), but before lindas become unusable.<br /> |
| 612 | The finalizer receives a single argument, a <tt>bool</tt> indicating whether all Lanes are successfully terminated at that point. It is possible to inspect them with <a href="#tracking">tracking</a>.<br /> | 624 | The finalizer receives a single argument, a <code>bool</code> indicating whether all Lanes are successfully terminated at that point. It is possible to inspect them with <a href="#tracking">tracking</a>.<br /> |
| 613 | If there are still running lanes when the finalizer returns: If the finalizer returned <tt>"freeze"</tt>, Lanes will freeze inside the Universe <tt>__gc</tt>. Any other value will cause Lanes to raise it as an error. If there is no return value, a default message will be used. | 625 | If there are still running lanes when the finalizer returns: If the finalizer returned <code>"freeze"</code>, Lanes will freeze inside the Universe <code>__gc</code>. Any other value will cause Lanes to raise it as an error. If there is no return value, a default message will be used. |
| 614 | </p> | 626 | </p> |
| 615 | 627 | ||
| 616 | <hr/> | 628 | <hr/> |
| @@ -623,13 +635,15 @@ | |||
| 623 | <table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> | 635 | <table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> |
| 624 | <tr> | 636 | <tr> |
| 625 | <td> | 637 | <td> |
| 626 | <pre> local lanes = require "lanes"</pre> | 638 | <pre> |
| 627 | <br /> | 639 | local lanes = require "lanes" |
| 628 | <pre> f = lanes.gen(function(n) return 2 * n end)</pre> | 640 | |
| 629 | <pre> a = f(1)</pre> | 641 | f = lanes.gen(function(n) return 2 * n end) |
| 630 | <pre> b = f(2)</pre> | 642 | a = f(1) |
| 631 | <br /> | 643 | b = f(2) |
| 632 | <pre> print(a[1], b[1]) -- 2 4</pre> | 644 | |
| 645 | print(a[1], b[1]) -- 2 4 | ||
| 646 | </pre> | ||
| 633 | </td> | 647 | </td> |
| 634 | </tr> | 648 | </tr> |
| 635 | </table> | 649 | </table> |
| @@ -637,191 +651,182 @@ | |||
| 637 | <table border=1 bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> | 651 | <table border=1 bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> |
| 638 | <tr> | 652 | <tr> |
| 639 | <td> | 653 | <td> |
| 640 | <pre> func = lanes.gen([libs_str | opt_tbl [, ...],] lane_func)</pre> | 654 | <pre> |
| 641 | <pre> lane_h = func(...)</pre> | 655 | func = lanes.gen([libs_str | opt_tbl [, ...],] lane_func) |
| 656 | lane_h = func(...) | ||
| 657 | </pre> | ||
| 642 | </td> | 658 | </td> |
| 643 | </tr> | 659 | </tr> |
| 644 | </table> | 660 | </table> |
| 645 | 661 | ||
| 646 | <p> | 662 | <p> |
| 647 | 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. | 663 | The function returned by <code>lanes.gen()</code> 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. |
| 648 | <br /> | 664 | <br /> |
| 649 | 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. | 665 | Alternatively, <code>lane_func</code> 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 <code>lua_dump</code>, used internally to transfer functions to the lane. |
| 650 | </p> | 666 | </p> |
| 651 | 667 | ||
| 652 | <p> | 668 | <p> |
| 653 | Lanes automatically copies upvalues over to the new lanes, so you need not wrap all the required elements into one 'wrapper' function. If <tt>lane_func</tt> uses some local values, or local functions, they will be there also in the new lanes. | 669 | Lanes automatically copies upvalues over to the new lanes, so you need not wrap all the required elements into one 'wrapper' function. If <code>lane_func</code> uses some local values, or local functions, they will be there also in the new lanes. |
| 654 | </p> | 670 | </p> |
| 655 | 671 | ||
| 656 | <p> | 672 | <p> |
| 657 | <code>libs_str</code> defines the standard libraries made available to the new Lua state: | 673 | <code>libs_str</code> defines the standard libraries made available to the new Lua state: |
| 658 | <table style="width:100%"> | 674 | <table style="width:100%" class="striped"> |
| 675 | <tr> | ||
| 676 | <th style="width:10%">name</th> | ||
| 677 | <th style="width:5%"></th> | ||
| 678 | <th style="width:85%">definition</th> | ||
| 679 | </tr> | ||
| 659 | <tr> | 680 | <tr> |
| 660 | <td style="width:5%"></td> | ||
| 661 | <td> | 681 | <td> |
| 662 | <tt>nil</tt> | 682 | <code>nil</code> |
| 663 | </td> | 683 | </td> |
| 664 | <td style="width:5%"></td> | 684 | <td /> |
| 665 | <td>no standard libraries (default)</td> | 685 | <td>no standard libraries (default)</td> |
| 666 | </tr> | 686 | </tr> |
| 667 | <tr> | 687 | <tr> |
| 668 | <td /> | ||
| 669 | <td> | 688 | <td> |
| 670 | <tt>"base"</tt> | 689 | <code>"base"</code> |
| 671 | </td> | 690 | </td> |
| 672 | <td /> | 691 | <td /> |
| 673 | <td> | 692 | <td> |
| 674 | <tt>_G</tt> namespace (the default function environment): <tt>print</tt>, <tt>assert</tt>, <tt>dofile</tt>, etc. | 693 | <code>_G</code> namespace (the default function environment): <code>print</code>, <code>assert</code>, <code>dofile</code>, etc. |
| 675 | </td> | 694 | </td> |
| 676 | </tr> | 695 | </tr> |
| 677 | <tr> | 696 | <tr> |
| 678 | <td /> | ||
| 679 | <td> | 697 | <td> |
| 680 | <tt>"bit"</tt> | 698 | <code>"bit"</code> |
| 681 | </td> | 699 | </td> |
| 682 | <td /> | 700 | <td /> |
| 683 | <td> | 701 | <td> |
| 684 | <tt>bit.*</tt> namespace (LuaJIT) | 702 | <code>bit.*</code> namespace (LuaJIT) |
| 685 | </td> | 703 | </td> |
| 686 | </tr> | 704 | </tr> |
| 687 | <tr> | 705 | <tr> |
| 688 | <td /> | ||
| 689 | <td> | 706 | <td> |
| 690 | <tt>"bit32"</tt> | 707 | <code>"bit32"</code> |
| 691 | </td> | 708 | </td> |
| 692 | <td /> | 709 | <td /> |
| 693 | <td> | 710 | <td> |
| 694 | <tt>bit32.*</tt> namespace (Lua 5.1 and 5.2) | 711 | <code>bit32.*</code> namespace (Lua 5.1 and 5.2) |
| 695 | </td> | 712 | </td> |
| 696 | </tr> | 713 | </tr> |
| 697 | <tr> | 714 | <tr> |
| 698 | <td /> | ||
| 699 | <td> | 715 | <td> |
| 700 | <tt>"coroutine"</tt> | 716 | <code>"coroutine"</code> |
| 701 | </td> | 717 | </td> |
| 702 | <td /> | 718 | <td /> |
| 703 | <td> | 719 | <td> |
| 704 | <tt>coroutine.*</tt> namespace (part of base in Lua 5.1 and 5.2) | 720 | <code>coroutine.*</code> namespace (part of <code>base</code> in Lua 5.1 and 5.2) |
| 705 | </td> | 721 | </td> |
| 706 | </tr> | 722 | </tr> |
| 707 | <tr> | 723 | <tr> |
| 708 | <td /> | ||
| 709 | <td> | 724 | <td> |
| 710 | <tt>"debug"</tt> | 725 | <code>"debug"</code> |
| 711 | </td> | 726 | </td> |
| 712 | <td /> | 727 | <td /> |
| 713 | <td> | 728 | <td> |
| 714 | <tt>debug.*</tt> namespace | 729 | <code>debug.*</code> namespace |
| 715 | </td> | 730 | </td> |
| 716 | </tr> | 731 | </tr> |
| 717 | <tr> | 732 | <tr> |
| 718 | <td /> | ||
| 719 | <td> | 733 | <td> |
| 720 | <tt>"ffi"</tt> | 734 | <code>"ffi"</code> |
| 721 | </td> | 735 | </td> |
| 722 | <td /> | 736 | <td /> |
| 723 | <td> | 737 | <td> |
| 724 | <tt>ffi.*</tt> namespace (LuaJIT) | 738 | <code>ffi.*</code> namespace (LuaJIT) |
| 725 | </td> | 739 | </td> |
| 726 | </tr> | 740 | </tr> |
| 727 | <tr> | 741 | <tr> |
| 728 | <td /> | ||
| 729 | <td> | 742 | <td> |
| 730 | <tt>"io"</tt> | 743 | <code>"io"</code> |
| 731 | </td> | 744 | </td> |
| 732 | <td /> | 745 | <td /> |
| 733 | <td> | 746 | <td> |
| 734 | <tt>io.*</tt> namespace | 747 | <code>io.*</code> namespace |
| 735 | </td> | 748 | </td> |
| 736 | </tr> | 749 | </tr> |
| 737 | <tr> | 750 | <tr> |
| 738 | <td /> | ||
| 739 | <td> | 751 | <td> |
| 740 | <tt>"jit"</tt> | 752 | <code>"jit"</code> |
| 741 | </td> | 753 | </td> |
| 742 | <td /> | 754 | <td /> |
| 743 | <td> | 755 | <td> |
| 744 | <tt>jit.*</tt> namespace (LuaJIT) | 756 | <code>jit.*</code> namespace (LuaJIT) |
| 745 | </td> | 757 | </td> |
| 746 | </tr> | 758 | </tr> |
| 747 | <tr> | 759 | <tr> |
| 748 | <td /> | ||
| 749 | <td> | 760 | <td> |
| 750 | <tt>"math"</tt> | 761 | <code>"math"</code> |
| 751 | </td> | 762 | </td> |
| 752 | <td /> | 763 | <td /> |
| 753 | <td> | 764 | <td> |
| 754 | <tt>math.*</tt> namespace | 765 | <code>math.*</code> namespace |
| 755 | </td> | 766 | </td> |
| 756 | </tr> | 767 | </tr> |
| 757 | <tr> | 768 | <tr> |
| 758 | <td /> | ||
| 759 | <td> | 769 | <td> |
| 760 | <tt>"os"</tt> | 770 | <code>"os"</code> |
| 761 | </td> | 771 | </td> |
| 762 | <td /> | 772 | <td /> |
| 763 | <td> | 773 | <td> |
| 764 | <tt>os.*</tt> namespace | 774 | <code>os.*</code> namespace |
| 765 | </td> | 775 | </td> |
| 766 | </tr> | 776 | </tr> |
| 767 | <tr> | 777 | <tr> |
| 768 | <td /> | ||
| 769 | <td> | 778 | <td> |
| 770 | <tt>"package"</tt> | 779 | <code>"package"</code> |
| 771 | </td> | 780 | </td> |
| 772 | <td /> | 781 | <td /> |
| 773 | <td> | 782 | <td> |
| 774 | <tt>package.*</tt> namespace and <tt>require</tt> | 783 | <code>package.*</code> namespace and <code>require</code> |
| 775 | </td> | 784 | </td> |
| 776 | </tr> | 785 | </tr> |
| 777 | <tr> | 786 | <tr> |
| 778 | <td /> | ||
| 779 | <td> | 787 | <td> |
| 780 | <tt>"string"</tt> | 788 | <code>"string"</code> |
| 781 | </td> | 789 | </td> |
| 782 | <td /> | 790 | <td /> |
| 783 | <td> | 791 | <td> |
| 784 | <tt>string.*</tt> namespace | 792 | <code>string.*</code> namespace |
| 785 | </td> | 793 | </td> |
| 786 | </tr> | 794 | </tr> |
| 787 | <tr> | 795 | <tr> |
| 788 | <td /> | ||
| 789 | <td> | 796 | <td> |
| 790 | <tt>"table"</tt> | 797 | <code>"table"</code> |
| 791 | </td> | 798 | </td> |
| 792 | <td /> | 799 | <td /> |
| 793 | <td> | 800 | <td> |
| 794 | <tt>table.*</tt> namespace | 801 | <code>table.*</code> namespace |
| 795 | </td> | 802 | </td> |
| 796 | </tr> | 803 | </tr> |
| 797 | <tr> | 804 | <tr> |
| 798 | <td /> | ||
| 799 | <td> | 805 | <td> |
| 800 | <tt>"utf8"</tt> | 806 | <code>"utf8"</code> |
| 801 | </td> | 807 | </td> |
| 802 | <td /> | 808 | <td /> |
| 803 | <td> | 809 | <td> |
| 804 | <tt>utf8.*</tt> namespace (Lua 5.3 and above) | 810 | <code>utf8.*</code> namespace (Lua 5.3 and above) |
| 805 | </td> | 811 | </td> |
| 806 | </tr> | 812 | </tr> |
| 807 | <tr> | 813 | <tr> |
| 808 | <td /> | ||
| 809 | <td> | 814 | <td> |
| 810 | <tt>"*"</tt> | 815 | <code>"*"</code> |
| 811 | </td> | 816 | </td> |
| 812 | <td /> | 817 | <td /> |
| 813 | <td> | 818 | <td> |
| 814 | All standard libraries (including those specific to LuaJIT and not listed above), as well as <tt>lanes_core</tt>. This must be used alone. | 819 | All standard libraries (including those specific to LuaJIT and not listed above), as well as <code>lanes_core</code>. This must be used alone. |
| 815 | </td> | 820 | </td> |
| 816 | </tr> | 821 | </tr> |
| 817 | </table> | 822 | </table> |
| 818 | </p> | 823 | </p> |
| 819 | 824 | ||
| 820 | <p> | 825 | <p> |
| 821 | Any non-<tt>nil</tt> value causes initialization of <tt>"base"</tt> and <tt>"jit"</tt> (the latter only for LuaJIT-based builds).<br /> | 826 | Any non-<code>nil</code> value causes initialization of <code>"base"</code> and <code>"jit"</code> (the latter only for LuaJIT-based builds).<br /> |
| 822 | Library names may contain characters matching <tt>std::isalnum(c_) || c_ == '.' || c_ == '-' || c_ == '_'</tt>. Anything else is considered a valid name separator.<br /> | 827 | Library names may contain characters matching <code>std::isalnum(c_) || c_ == '.' || c_ == '-' || c_ == '_'</code>. Anything else is considered a valid name separator.<br /> |
| 823 | Trying to load a library not supported by the running Lua flavor will raise an error, unless the library name is postfixed with a <tt>'?'</tt>.<br /> | 828 | Trying to load a library not supported by the running Lua flavor will raise an error, unless the library name is postfixed with a <code>'?'</code>.<br /> |
| 824 | Initializing the standard libs takes a bit of time at each lane invocation. This is the main reason why "no libraries" is the default. | 829 | Initializing the standard libraries takes a bit of time at each lane creation. This is the main reason why "no libraries" is the default. |
| 825 | </p> | 830 | </p> |
| 826 | 831 | ||
| 827 | <p> | 832 | <p> |
| @@ -830,11 +835,11 @@ | |||
| 830 | 835 | ||
| 831 | <p> | 836 | <p> |
| 832 | 837 | ||
| 833 | <table border="1" cellpadding="10" style="width:100%"> | 838 | <table border="1" cellpadding="10" style="width:100%" class="striped"> |
| 834 | <tr> | 839 | <tr> |
| 835 | <th style="width:15%">name</th> | 840 | <th style="width:15%">name</th> |
| 836 | <th style="width:15%">value</th> | 841 | <th style="width:10%">value</th> |
| 837 | <th style="width:70%">definition</th> | 842 | <th style="width:75%">definition</th> |
| 838 | </tr> | 843 | </tr> |
| 839 | <tr valign=top> | 844 | <tr valign=top> |
| 840 | <td> | 845 | <td> |
| @@ -842,7 +847,7 @@ | |||
| 842 | </td> | 847 | </td> |
| 843 | <td>table</td> | 848 | <td>table</td> |
| 844 | <td> | 849 | <td> |
| 845 | Sets the globals table for the launched threads. This can be used for giving them constants. The key/value pairs of <tt>table</tt> are transfered in the lane globals after the libraries have been loaded and the modules required.<br /> | 850 | Sets the globals table for the launched threads. This can be used for giving them constants. The key/value pairs of <code>table</code> are transfered in the lane globals after the libraries have been loaded and the modules required.<br /> |
| 846 | The global values of different lanes are in no manner connected; modifying one will only affect the particular lane. | 851 | The global values of different lanes are in no manner connected; modifying one will only affect the particular lane. |
| 847 | </td> | 852 | </td> |
| 848 | </tr> | 853 | </tr> |
| @@ -853,9 +858,9 @@ | |||
| 853 | <td>table</td> | 858 | <td>table</td> |
| 854 | <td> | 859 | <td> |
| 855 | Lists modules that have to be required in order to be able to transfer functions/userdata they exposed. Non-Lua functions are <a href="#function_notes">searched in lookup tables</a>. | 860 | Lists modules that have to be required in order to be able to transfer functions/userdata they exposed. Non-Lua functions are <a href="#function_notes">searched in lookup tables</a>. |
| 856 | These tables are built from the modules listed here. <tt>required</tt> must be an array of strings, each one being the name of a module to be required. Each module is required with <tt>require()</tt> before the lane function is invoked. | 861 | These tables are built from the modules listed here. <code>required</code> must be an array of strings, each one being the name of a module to be required. Each module is required with <code>require()</code> before the lane function is invoked. |
| 857 | So, from the required module's point of view, requiring it manually from inside the lane body or having it required this way doesn't change anything. From the lane body's point of view, the only difference is that a module not creating a global won't be accessible. | 862 | So, from the required module's point of view, requiring it manually from inside the lane body or having it required this way doesn't change anything. From the lane body's point of view, the only difference is that a module not creating a global won't be accessible. |
| 858 | Therefore, a lane body will also have to require a module manually, but this won't do anything more (see Lua's <tt>require</tt> documentation). <br /> | 863 | Therefore, a lane body will also have to require a module manually, but this won't do anything more (see Lua's <code>require</code> documentation). <br /> |
| 859 | ATTEMPTING TO TRANSFER A FUNCTION REGISTERED BY A MODULE NOT LISTED HERE WILL RAISE AN ERROR. | 864 | ATTEMPTING TO TRANSFER A FUNCTION REGISTERED BY A MODULE NOT LISTED HERE WILL RAISE AN ERROR. |
| 860 | </td> | 865 | </td> |
| 861 | </tr> | 866 | </tr> |
| @@ -865,8 +870,8 @@ | |||
| 865 | </td> | 870 | </td> |
| 866 | <td>string</td> | 871 | <td>string</td> |
| 867 | <td> | 872 | <td> |
| 868 | Sets the error reporting mode. One of <tt>"minimal"</tt> (the default), <tt>"basic"</tt>, <tt>"extended"</tt>.<br /> | 873 | Sets the error reporting mode. One of <code>"minimal"</code> (the default), <code>"basic"</code>, <code>"extended"</code>.<br /> |
| 869 | <tt>"minimal"</tt> yields only the location of the error.<br /> | 874 | <code>"minimal"</code> yields only the location of the error.<br /> |
| 870 | The other two options yield a full stack trace, with different amounts of data extracted from the debug infos. See <a href="#results">Results</a>. | 875 | The other two options yield a full stack trace, with different amounts of data extracted from the debug infos. See <a href="#results">Results</a>. |
| 871 | </td> | 876 | </td> |
| 872 | </tr> | 877 | </tr> |
| @@ -876,7 +881,7 @@ | |||
| 876 | </td> | 881 | </td> |
| 877 | <td>string</td> | 882 | <td>string</td> |
| 878 | <td> | 883 | <td> |
| 879 | Name of the lane. If <tt>"auto"</tt>, name is built from <tt>ar.short_src:ar.linedefined</tt>. Can be changed later from the inside of the lane with <tt>lane_threadname()</tt> (see below). | 884 | Name of the lane. If <code>"auto"</code>, name is built from <code>ar.short_src:ar.linedefined</code>. Can be changed later from the inside of the lane with <code>lane_threadname()</code> (see below). |
| 880 | </td> | 885 | </td> |
| 881 | </tr> | 886 | </tr> |
| 882 | <tr id=".gc_cb" valign=top> | 887 | <tr id=".gc_cb" valign=top> |
| @@ -885,7 +890,7 @@ | |||
| 885 | </td> | 890 | </td> |
| 886 | <td>function</td> | 891 | <td>function</td> |
| 887 | <td> | 892 | <td> |
| 888 | Callback that gets invoked when the lane is garbage collected. The function receives two arguments (the lane name and a string, either <tt>"closed"</tt> or <tt>"selfdestruct"</tt>). | 893 | Callback that gets invoked when the lane is garbage collected. The function receives two arguments (the lane name and a string, either <code>"closed"</code> or <code>"selfdestruct"</code>). |
| 889 | </td> | 894 | </td> |
| 890 | </tr> | 895 | </tr> |
| 891 | <tr valign=top> | 896 | <tr valign=top> |
| @@ -895,10 +900,10 @@ | |||
| 895 | </td> | 900 | </td> |
| 896 | <td>integer</td> | 901 | <td>integer</td> |
| 897 | <td> | 902 | <td> |
| 898 | <tt>priority</tt>: The priority of lanes in the range <tt>[-3,+3]</tt> (default is 0). These values are a mapping over the actual priority range of the underlying implementation.<br /> | 903 | <code>priority</code>: The priority of lanes in the range <code>[-3,+3]</code> (default is 0). These values are a mapping over the actual priority range of the underlying implementation.<br /> |
| 899 | <tt>native_priority</tt>: The priority of lanes in a platform-dependent range. Use <a href="#priority"><tt>lanes.thread_priority_range()</tt></a> to query said range. | 904 | <code>native_priority</code>: The priority of lanes in a platform-dependent range. Use <a href="#priority"><code>lanes.thread_priority_range()</code></a> to query said range. |
| 900 | Implementation and dependability of priorities varies by platform. Especially Linux kernel 2.6 is not supporting priorities in user mode.<br /> | 905 | Implementation and dependability of priorities varies by platform. Especially Linux kernel 2.6 is not supporting priorities in user mode.<br /> |
| 901 | A lane can also change its own thread priority dynamically with <a href="#priority"><tt>lanes.set_thread_priority()</tt></a>. | 906 | A lane can also change its own thread priority dynamically with <a href="#priority"><code>lanes.set_thread_priority()</code></a>. |
| 902 | </td> | 907 | </td> |
| 903 | </tr> | 908 | </tr> |
| 904 | <tr valign=top> | 909 | <tr valign=top> |
| @@ -908,23 +913,23 @@ | |||
| 908 | <td> table</td> | 913 | <td> table</td> |
| 909 | <td> | 914 | <td> |
| 910 | Specifying it when <code>libs_str</code> doesn't cause the <code>package</code> library to be loaded will generate an error.<br /> | 915 | Specifying it when <code>libs_str</code> doesn't cause the <code>package</code> library to be loaded will generate an error.<br /> |
| 911 | If not specified, the created lane will receive the current values of <tt>package</tt>. Only <tt>path</tt>, <tt>cpath</tt>, <tt>preload</tt> and <tt>loaders</tt> (Lua 5.1)/<tt>searchers</tt> (Lua 5.2) are transfered. | 916 | If not specified, the created lane will receive the current values of <code>package</code>. Only <code>path</code>, <code>cpath</code>, <code>preload</code> and <code>loaders</code> (Lua 5.1)/<code>searchers</code> (Lua 5.2) are transfered. |
| 912 | </td> | 917 | </td> |
| 913 | </tr> | 918 | </tr> |
| 914 | </table> | 919 | </table> |
| 915 | 920 | ||
| 916 | <p> | 921 | <p> |
| 917 | Each lane gets a global function <tt>lane_threadname()</tt> that it can use anytime to do both read and change the thread name. Supported debuggers are Microsoft Visual Studio (for the C side) and <a href="https://github.com/unknownworlds/decoda">Decoda</a> (for the Lua side).<br /> | 922 | Each lane gets a global function <code>lane_threadname()</code> that it can use anytime to do both read and change the thread name. Supported debuggers are Microsoft Visual Studio (for the C side) and <a href="https://github.com/unknownworlds/decoda">Decoda</a> (for the Lua side).<br /> |
| 918 | Change <tt>HAVE_DECODA_SUPPORT()</tt> in <tt>lanesconf.h</tt> to enable the Decoda support, that sets a special global variable <tt>decoda_name</tt> in the lane's state.<br /> | 923 | Change <code>HAVE_DECODA_SUPPORT()</code> in <code>lanesconf.h</code> to enable the Decoda support, that sets a special global variable <code>decoda_name</code> in the lane's state.<br /> |
| 919 | The name is stored inside the Lua state registry so that it is available for error reporting. Changing <tt>decoda_name</tt> doesn't affect this hidden name or the OS thread name reported by MSVC.<br /> | 924 | The name is stored inside the Lua state registry so that it is available for error reporting. Changing <code>decoda_name</code> doesn't affect this hidden name or the OS thread name reported by MSVC.<br /> |
| 920 | When Lanes is initialized by the first <a href="#initialization"><tt>lanes.configure()</tt></a> call, <tt>"main"</tt> is stored in the registry in the same fashion (but <tt>decoda_name</tt> and the OS thread name are left unchanged).<br /> | 925 | When Lanes is initialized by the first <a href="#initialization"><code>lanes.configure()</code></a> call, <code>"main"</code> is stored in the registry in the same fashion (but <code>decoda_name</code> and the OS thread name are left unchanged).<br /> |
| 921 | The lane also has a method <tt>lane:get_threadname()</tt> that gives access to that name from the caller side (returns <tt>"<unnamed>"</tt> if unset).<br /> | 926 | The lane also has a method <code>lane:get_threadname()</code> that gives access to that name from the caller side (returns <code>"<unnamed>"</code> if unset).<br /> |
| 922 | With Lua 5.4+, Lanes have a <tt>__close</tt> metamethod, meaning they can be declared to-be-closed. <tt>__close</tt> calls <tt>lane:join(nil)</tt>. | 927 | With Lua 5.4+, Lanes have a <code>__close</code> metamethod, meaning they can be declared to-be-closed. <code>__close</code> calls <code>lane:join(nil)</code>. |
| 923 | </p> | 928 | </p> |
| 924 | 929 | ||
| 925 | <p> | 930 | <p> |
| 926 | If a lane body pulls a C function or userdata exposed by a module required before Lanes itself (thus not through a hooked <tt>require()</tt>), the lane generator creation will raise an error. | 931 | If a lane body pulls a C function or userdata exposed by a module required before Lanes itself (thus not through a hooked <code>require()</code>), the lane generator creation will raise an error. |
| 927 | The name in the message is a path where it was found by scanning <tt>_G</tt> and the registry. As a utility, the name guessing functionality is exposed as such: | 932 | The name in the message is a path where it was found by scanning <code>_G</code> and the registry. As a utility, the name guessing functionality is exposed as such: |
| 928 | 933 | ||
| 929 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> | 934 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> |
| 930 | <tr> | 935 | <tr> |
| @@ -938,7 +943,7 @@ | |||
| 938 | <h3 id="coroutines">Coroutine lanes</h3> | 943 | <h3 id="coroutines">Coroutine lanes</h3> |
| 939 | 944 | ||
| 940 | <p> | 945 | <p> |
| 941 | 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>. | 946 | It is possible to have the lane body run inside the lane as a coroutine. For this, just use <code>lanes.coro()</code> instead of <code>lanes.gen()</code>. |
| 942 | 947 | ||
| 943 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> | 948 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> |
| 944 | <tr> | 949 | <tr> |
| @@ -948,9 +953,9 @@ | |||
| 948 | </tr> | 953 | </tr> |
| 949 | </table> | 954 | </table> |
| 950 | 955 | ||
| 951 | Coroutine lanes operate mostly like regular coroutines. They can use <tt>coroutine.yield()</tt> normally.<br /> | 956 | Coroutine lanes operate mostly like regular coroutines. They can use <code>coroutine.yield()</code> normally.<br /> |
| 952 | A yielded coroutine lane has a <tt>"suspended"</tt> status. It can be resumed with <tt>lane_h:resume(values...), which returns the yielded values</tt>. | 957 | A yielded coroutine lane has a <code>"suspended"</code> status. It can be resumed with <code>lane_h:resume(values...), which returns the yielded values</code>. |
| 953 | The latter can also be the returned values of <tt>lane_h:join()</tt> or accessed by regular lane indexing (see <a href="#results">Results and errors</a>).<br /> | 958 | The latter can also be the returned values of <code>lane_h:join()</code> or accessed by regular lane indexing (see <a href="#results">Results and errors</a>).<br /> |
| 954 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> | 959 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> |
| 955 | <tr> | 960 | <tr> |
| 956 | <td> | 961 | <td> |
| @@ -959,8 +964,8 @@ | |||
| 959 | </tr> | 964 | </tr> |
| 960 | </table> | 965 | </table> |
| 961 | 966 | ||
| 962 | Just like regular coroutines, the reply values passed to <tt>h:resume()</tt> are returned to the lane body at the <tt>coroutine.yield()</tt> point.<br /> | 967 | Just like regular coroutines, the reply values passed to <code>h:resume()</code> are returned to the lane body at the <code>coroutine.yield()</code> point.<br /> |
| 963 | If a coroutine lane is suspended when it is joined either by indexing or <tt>lane_h:join()</tt>, active to-be-closed variables are closed at that point, and the Lane can no longer be resumed. | 968 | If a coroutine lane is suspended when it is joined either by indexing or <code>lane_h:join()</code>, active to-be-closed variables are closed at that point, and the Lane can no longer be resumed. |
| 964 | </p> | 969 | </p> |
| 965 | <h3>Free running lanes</h3> | 970 | <h3>Free running lanes</h3> |
| 966 | 971 | ||
| @@ -994,9 +999,9 @@ | |||
| 994 | <p> | 999 | <p> |
| 995 | Besides setting a default priority in the generator <a href="#generator_settings">settings</a>, each thread can change its own priority at will. This is also true for the main Lua state. | 1000 | Besides setting a default priority in the generator <a href="#generator_settings">settings</a>, each thread can change its own priority at will. This is also true for the main Lua state. |
| 996 | <br /> | 1001 | <br /> |
| 997 | <tt>lanes.thread_priority_range()</tt> returns the range of acceptable mapped values. If nothing is specified, should be <tt>[-3,3]</tt> or <tt>[0,3]</tt>, depending on the threading implementation. | 1002 | <code>lanes.thread_priority_range()</code> returns the range of acceptable mapped values. If nothing is specified, should be <code>[-3,3]</code> or <code>[0,3]</code>, depending on the threading implementation. |
| 998 | <br /> | 1003 | <br /> |
| 999 | <tt>lanes.thread_priority_range('native')</tt> returns the range of acceptable native values. The actual values are threading implementation dependent. And some implementations can only accept some values inside that range. YMMV. | 1004 | <code>lanes.thread_priority_range('native')</code> returns the range of acceptable native values. The actual values are threading implementation dependent. And some implementations can only accept some values inside that range. YMMV. |
| 1000 | </p> | 1005 | </p> |
| 1001 | 1006 | ||
| 1002 | 1007 | ||
| @@ -1028,7 +1033,7 @@ | |||
| 1028 | </tr> | 1033 | </tr> |
| 1029 | </table> | 1034 | </table> |
| 1030 | <p> | 1035 | <p> |
| 1031 | Read back the value set during lane generation, one of <tt>"basic", "minimal", "extended"</tt>. | 1036 | Read back the value set during lane generation, one of <code>"basic", "minimal", "extended"</code>. |
| 1032 | </p> | 1037 | </p> |
| 1033 | 1038 | ||
| 1034 | <!-- status +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 1039 | <!-- status +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
| @@ -1044,103 +1049,89 @@ | |||
| 1044 | </table> | 1049 | </table> |
| 1045 | 1050 | ||
| 1046 | <p> | 1051 | <p> |
| 1047 | The current execution state of a lane can be read via its <tt>status</tt> member, providing one of these values: | 1052 | The current execution state of a lane can be read via its <code>status</code> member, providing one of these values: |
| 1048 | 1053 | ||
| 1049 | <table style="width:100%"> | 1054 | <table style="width:100%" class="striped"> |
| 1055 | <tr> | ||
| 1056 | <th style="width:15%">name</th> | ||
| 1057 | <th style="width:85%">definition</th> | ||
| 1058 | </tr> | ||
| 1050 | <tr> | 1059 | <tr> |
| 1051 | <td style="width:5%"></td> | ||
| 1052 | <td> | 1060 | <td> |
| 1053 | <tt>"pending"</tt> | 1061 | <code>"pending"</code> |
| 1054 | </td> | 1062 | </td> |
| 1055 | <td style="width:5%"></td> | ||
| 1056 | <td> | 1063 | <td> |
| 1057 | Not started yet. Shouldn't stay very long in that state. | 1064 | Not started yet. Shouldn't stay very long in that state. |
| 1058 | </td> | 1065 | </td> |
| 1059 | </tr> | 1066 | </tr> |
| 1060 | <tr> | 1067 | <tr> |
| 1061 | <td /> | ||
| 1062 | <td> | 1068 | <td> |
| 1063 | <tt> | 1069 | <code> |
| 1064 | "running" | 1070 | "running" |
| 1065 | </tt> | 1071 | </code> |
| 1066 | </td> | 1072 | </td> |
| 1067 | <td /> | ||
| 1068 | <td> | 1073 | <td> |
| 1069 | Running, not suspended on a <a href="#lindas">linda</a> call, or yielded on a <tt>coroutine.yield()</tt> call. | 1074 | Running, not suspended on a <a href="#lindas">linda</a> call, or yielded on a <code>coroutine.yield()</code> call. |
| 1070 | </td> | 1075 | </td> |
| 1071 | </tr> | 1076 | </tr> |
| 1072 | <tr> | 1077 | <tr> |
| 1073 | <td /> | ||
| 1074 | <td> | 1078 | <td> |
| 1075 | <tt> | 1079 | <code> |
| 1076 | "suspended" | 1080 | "suspended" |
| 1077 | </tt> | 1081 | </code> |
| 1078 | </td> | 1082 | </td> |
| 1079 | <td /> | ||
| 1080 | <td> | 1083 | <td> |
| 1081 | Coroutine lane stopped at a <tt>coroutine.yield()</tt> point. | 1084 | Coroutine lane stopped at a <code>coroutine.yield()</code> point. |
| 1082 | </td> | 1085 | </td> |
| 1083 | </tr> | 1086 | </tr> |
| 1084 | <tr> | 1087 | <tr> |
| 1085 | <td /> | ||
| 1086 | <td> | 1088 | <td> |
| 1087 | <tt> | 1089 | <code> |
| 1088 | "resuming" | 1090 | "resuming" |
| 1089 | </tt> | 1091 | </code> |
| 1090 | </td> | 1092 | </td> |
| 1091 | <td /> | ||
| 1092 | <td> | 1093 | <td> |
| 1093 | Parent state called <tt>lane_h:resume()</tt> on a suspended <a href="#coroutines">coroutine</a> lane, but the lane hasn't yet actually resumed execution. | 1094 | Parent state called <code>lane_h:resume()</code> on a suspended <a href="#coroutines">coroutine</a> lane, but the lane hasn't yet actually resumed execution. |
| 1094 | </td> | 1095 | </td> |
| 1095 | </tr> | 1096 | </tr> |
| 1096 | <tr> | 1097 | <tr> |
| 1097 | <td /> | ||
| 1098 | <td> | 1098 | <td> |
| 1099 | <tt> | 1099 | <code> |
| 1100 | "closing" | 1100 | "closing" |
| 1101 | </tt> | 1101 | </code> |
| 1102 | </td> | 1102 | </td> |
| 1103 | <td /> | ||
| 1104 | <td> | 1103 | <td> |
| 1105 | Happens only inside a <tt>join()</tt>/indexation call to unblock a suspended <a href="#coroutines">coroutine</a> lane so that it can join properly. In theory not observable by lanes client code, but who knows. | 1104 | Happens only inside a <code>join()</code>/indexation call to unblock a suspended <a href="#coroutines">coroutine</a> lane so that it can join properly. In theory not observable by lanes client code, but who knows. |
| 1106 | </td> | 1105 | </td> |
| 1107 | </tr> | 1106 | </tr> |
| 1108 | <tr> | 1107 | <tr> |
| 1109 | <td /> | ||
| 1110 | <td> | 1108 | <td> |
| 1111 | <tt>"waiting"</tt> | 1109 | <code>"waiting"</code> |
| 1112 | </td> | 1110 | </td> |
| 1113 | <td /> | ||
| 1114 | <td> | 1111 | <td> |
| 1115 | Waiting at a <a href="#lindas">linda</a> <tt>:receive()</tt> or <tt>:send()</tt>. | 1112 | Waiting at a <a href="#lindas">linda</a> <code>:receive()</code> or <code>:send()</code>. |
| 1116 | </td> | 1113 | </td> |
| 1117 | </tr> | 1114 | </tr> |
| 1118 | <tr> | 1115 | <tr> |
| 1119 | <td /> | ||
| 1120 | <td> | 1116 | <td> |
| 1121 | <tt>"done"</tt> | 1117 | <code>"done"</code> |
| 1122 | </td> | 1118 | </td> |
| 1123 | <td /> | ||
| 1124 | <td> | 1119 | <td> |
| 1125 | Finished executing (results are ready). | 1120 | Finished executing (results are ready). |
| 1126 | </td> | 1121 | </td> |
| 1127 | </tr> | 1122 | </tr> |
| 1128 | <tr> | 1123 | <tr> |
| 1129 | <td /> | ||
| 1130 | <td> | 1124 | <td> |
| 1131 | <tt>"error"</tt> | 1125 | <code>"error"</code> |
| 1132 | </td> | 1126 | </td> |
| 1133 | <td /> | ||
| 1134 | <td> | 1127 | <td> |
| 1135 | Met an error (reading results will propagate it). | 1128 | Met an error (reading results will propagate it). |
| 1136 | </td> | 1129 | </td> |
| 1137 | </tr> | 1130 | </tr> |
| 1138 | <tr> | 1131 | <tr> |
| 1139 | <td /> | ||
| 1140 | <td> | 1132 | <td> |
| 1141 | <tt>"cancelled"</tt> | 1133 | <code>"cancelled"</code> |
| 1142 | </td> | 1134 | </td> |
| 1143 | <td /> | ||
| 1144 | <td> | 1135 | <td> |
| 1145 | Received <a href="#cancelling">cancellation</a> and finished itself. | 1136 | Received <a href="#cancelling">cancellation</a> and finished itself. |
| 1146 | </td> | 1137 | </td> |
| @@ -1149,7 +1140,7 @@ | |||
| 1149 | </p> | 1140 | </p> |
| 1150 | 1141 | ||
| 1151 | <p> | 1142 | <p> |
| 1152 | This is similar to <tt>coroutine.status</tt>, which has: <tt>"running"</tt> / <tt>"suspended"</tt> / <tt>"normal"</tt> / <tt>"dead"</tt>. Not using the exact same names is intentional. | 1143 | This is similar to <code>coroutine.status</code>, which has: <code>"running"</code> / <code>"suspended"</code> / <code>"normal"</code> / <code>"dead"</code>. Not using the exact same names is intentional. |
| 1153 | </p> | 1144 | </p> |
| 1154 | 1145 | ||
| 1155 | 1146 | ||
| @@ -1166,9 +1157,9 @@ | |||
| 1166 | </table> | 1157 | </table> |
| 1167 | 1158 | ||
| 1168 | <p> | 1159 | <p> |
| 1169 | Only available if lane tracking is enabled by setting <a href="#track_lanes"><tt>track_lanes</tt></a>. | 1160 | Only available if lane tracking is enabled by setting <a href="#track_lanes"><code>track_lanes</code></a>. |
| 1170 | <br /> | 1161 | <br /> |
| 1171 | Returns an array table where each entry is a table containing a lane's name and status. Returns <tt>nil</tt> if no lane is running. | 1162 | Returns an array table where each entry is a table containing a lane's name and status. Returns <code>nil</code> if no lane is running. |
| 1172 | </p> | 1163 | </p> |
| 1173 | 1164 | ||
| 1174 | 1165 | ||
| @@ -1189,7 +1180,7 @@ | |||
| 1189 | </pre></td></tr></table> | 1180 | </pre></td></tr></table> |
| 1190 | 1181 | ||
| 1191 | <p> | 1182 | <p> |
| 1192 | Makes sure lane has finished or yielded, and gives its first (maybe only) return value. Other return values will be available in other <tt>lane_h</tt> indices. | 1183 | Makes sure lane has finished or yielded, and gives its first (maybe only) return value. Other return values will be available in other <code>lane_h</code> indices. |
| 1193 | <br /> | 1184 | <br /> |
| 1194 | If the lane ended in an error, it is propagated to master state at this place. | 1185 | If the lane ended in an error, it is propagated to master state at this place. |
| 1195 | </p> | 1186 | </p> |
| @@ -1199,23 +1190,23 @@ | |||
| 1199 | </pre></td></tr></table> | 1190 | </pre></td></tr></table> |
| 1200 | 1191 | ||
| 1201 | <p> | 1192 | <p> |
| 1202 | Waits until the lane finishes/yields, or <tt>timeout</tt> seconds have passed (forever if <tt>nil</tt>).<br /> | 1193 | Waits until the lane finishes/yields, or <code>timeout</code> seconds have passed (forever if <code>nil</code>).<br /> |
| 1203 | Unlike in reading the results in table fashion, errors are not propagated.<br /> | 1194 | Unlike in reading the results in table fashion, errors are not propagated.<br /> |
| 1204 | Possible return values are: | 1195 | Possible return values are: |
| 1205 | <ul> | 1196 | <ul> |
| 1206 | <li><tt>nil, "timeout"</tt> on timeout.</li> | 1197 | <li><code>nil, "timeout"</code> on timeout.</li> |
| 1207 | <li> | 1198 | <li> |
| 1208 | <tt>nil,err,stack_tbl</tt> if the lane hit an error. The contents of <tt>stack_tbl</tt> change with <a href="#.error_trace_level"><tt>error_trace_level</tt></a>.<br /> | 1199 | <code>nil,err,stack_tbl</code> if the lane hit an error. The contents of <code>stack_tbl</code> change with <a href="#.error_trace_level"><code>error_trace_level</code></a>.<br /> |
| 1209 | <ul> | 1200 | <ul> |
| 1210 | <li><tt>"minimal"</tt>: <tt>stack_tbl</tt> is <tt>nil</tt>.</li> | 1201 | <li><code>"minimal"</code>: <code>stack_tbl</code> is <code>nil</code>.</li> |
| 1211 | <li><tt>"basic"</tt>: <tt>stack_tbl</tt> is an array of <tt>"<filename>:<line>"</tt> strings. You can use <tt>table.concat()</tt> to format it to your liking (or just ignore it).</li> | 1202 | <li><code>"basic"</code>: <code>stack_tbl</code> is an array of <code>"<filename>:<line>"</code> strings. You can use <code>table.concat()</code> to format it to your liking (or just ignore it).</li> |
| 1212 | <li><tt>"extended"</tt>: <tt>stack_tbl</tt> is an array of tables containing info gathered with <tt>lua_getinfo()</tt> (<tt>"source"</tt>,<tt>"currentline"</tt>,<tt>"name"</tt>,<tt>"namewhat"</tt>,<tt>"what"</tt>).</li> | 1203 | <li><code>"extended"</code>: <code>stack_tbl</code> is an array of tables containing info gathered with <code>lua_getinfo()</code> (<code>"source"</code>,<code>"currentline"</code>,<code>"name"</code>,<code>"namewhat"</code>,<code>"what"</code>).</li> |
| 1213 | </ul> | 1204 | </ul> |
| 1214 | </li> | 1205 | </li> |
| 1215 | <li><tt>nil, lanes.cancel_error</tt> if the lane is in <tt>"cancelled"</tt> status (i.e. it was hard-cancelled, whether via a <a href="#lindas">linda</a> operation, a hook, or <tt>cancel_test()</tt> raising).</li> | 1206 | <li><code>nil, lanes.cancel_error</code> if the lane is in <code>"cancelled"</code> status (i.e. it was hard-cancelled, whether via a <a href="#lindas">linda</a> operation, a hook, or <code>cancel_test()</code> raising).</li> |
| 1216 | <li><tt>true [, returned-values]</tt>: The return values of the lane function.</li> | 1207 | <li><code>true [, returned-values]</code>: The return values of the lane function.</li> |
| 1217 | </ul> | 1208 | </ul> |
| 1218 | If the lane handle obtained from <tt>lanes.gen()</tt> is to-be-closed, closing the value will cause a call to <tt>join()</tt>. | 1209 | If the lane handle obtained from <code>lanes.gen()</code> is to-be-closed, closing the value will cause a call to <code>join()</code>. |
| 1219 | </p> | 1210 | </p> |
| 1220 | 1211 | ||
| 1221 | <table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> | 1212 | <table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> |
| @@ -1259,51 +1250,51 @@ | |||
| 1259 | </pre></td></tr></table> | 1250 | </pre></td></tr></table> |
| 1260 | 1251 | ||
| 1261 | <p> | 1252 | <p> |
| 1262 | <tt>cancel()</tt> sends a cancellation request to the lane. | 1253 | <code>cancel()</code> sends a cancellation request to the lane. |
| 1263 | <p> | 1254 | <p> |
| 1264 | 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 /> | 1255 | Returns <code>true, lane_h.status</code> if lane was already done (in <code>"done"</code>, <code>"error"</code> or <code>"cancelled"</code> status), or the cancellation was fruitful within <code>timeout_secs</code> timeout period.<br /> |
| 1265 | Returns <tt>false, "timeout"</tt> otherwise. | 1256 | Returns <code>false, "timeout"</code> otherwise. |
| 1266 | </p> | 1257 | </p> |
| 1267 | First argument is a <tt>mode</tt>. It can be one of: | 1258 | First argument is a <code>mode</code>. It can be one of: |
| 1268 | <ul> | 1259 | <ul> |
| 1269 | <li> | 1260 | <li> |
| 1270 | <tt>"soft"</tt>: Cancellation will only cause <tt>cancel_test()</tt> to return <tt>"soft"</tt>, so that the lane can cleanup manually. | 1261 | <code>"soft"</code>: Cancellation will only cause <code>cancel_test()</code> to return <code>"soft"</code>, so that the lane can cleanup manually. |
| 1271 | <br /> | 1262 | <br /> |
| 1272 | The <a href="#lindas">linda</a> will also check for cancellation inside blocking calls to early out based on its <tt>wake_period</tt>. | 1263 | The <a href="#lindas">linda</a> will also check for cancellation inside blocking calls to early out based on its <code>wake_period</code>. |
| 1273 | <br /> | 1264 | <br /> |
| 1274 | <tt>wake_lane</tt> defaults to <tt>false</tt>. | 1265 | <code>wake_lane</code> defaults to <code>false</code>. |
| 1275 | </li> | 1266 | </li> |
| 1276 | <li> | 1267 | <li> |
| 1277 | <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). | 1268 | <code>"hard"</code>: 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). |
| 1278 | <br /> | 1269 | <br /> |
| 1279 | If the lane isn't actually waiting on a <a href="#lindas">linda</a> when the request is issued, a lane calling <tt>cancel_test()</tt> will also raise <tt>lanes.cancel_error</tt>, unless <tt>cancel_test(true)</tt> is used, in which case it returns <tt>"hard"</tt> instead. | 1270 | If the lane isn't actually waiting on a <a href="#lindas">linda</a> when the request is issued, a lane calling <code>cancel_test()</code> will also raise <code>lanes.cancel_error</code>, unless <code>cancel_test(true)</code> is used, in which case it returns <code>"hard"</code> instead. |
| 1280 | <br /> | 1271 | <br /> |
| 1281 | <tt>wake_lane</tt> defaults to <tt>true</tt>. | 1272 | <code>wake_lane</code> defaults to <code>true</code>. |
| 1282 | </li> | 1273 | </li> |
| 1283 | <li> | 1274 | <li> |
| 1284 | <tt>"call"</tt>, <tt>"ret"</tt>, <tt>"line"</tt>, <tt>"count"</tt>: Asynchronously install the corresponding hook, then behave as <tt>"hard"</tt>. | 1275 | <code>"call"</code>, <code>"ret"</code>, <code>"line"</code>, <code>"count"</code>: Asynchronously install the corresponding hook, then behave as <code>"hard"</code>. |
| 1285 | <br /> | 1276 | <br /> |
| 1286 | If the lane has the opportunity to call <tt>cancel_test()</tt> before the hook is invoked, it will also raise <tt>lanes.cancel_error</tt> (or return <tt>"hard"</tt> if <tt>cancel_test(true)</tt> is used). | 1277 | If the lane has the opportunity to call <code>cancel_test()</code> before the hook is invoked, it will also raise <code>lanes.cancel_error</code> (or return <code>"hard"</code> if <code>cancel_test(true)</code> is used). |
| 1287 | </li> | 1278 | </li> |
| 1288 | <li> | 1279 | <li> |
| 1289 | <tt>"all"</tt>: Installs all hooks in one shot, just to be sure. | 1280 | <code>"all"</code>: Installs all hooks in one shot, just to be sure. |
| 1290 | </li> | 1281 | </li> |
| 1291 | </ul> | 1282 | </ul> |
| 1292 | <p> | 1283 | <p> |
| 1293 | If <tt>mode</tt> is not specified, it defaults to <tt>"hard"</tt>. | 1284 | If <code>mode</code> is not specified, it defaults to <code>"hard"</code>. |
| 1294 | </p> | 1285 | </p> |
| 1295 | </p> | 1286 | </p> |
| 1296 | <p> | 1287 | <p> |
| 1297 | 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>. | 1288 | If <code>wake_lane</code> is <code>true</code>, 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 <code>lanes.cancel_error</code>. |
| 1298 | </p> | 1289 | </p> |
| 1299 | <p> | 1290 | <p> |
| 1300 | <tt>timeout</tt> is an optional number >= 0. Defaults to infinite if left unspecified or <tt>nil</tt>. | 1291 | <code>timeout</code> is an optional number >= 0. Defaults to infinite if left unspecified or <code>nil</code>. |
| 1301 | </p> | 1292 | </p> |
| 1302 | <p> | 1293 | <p> |
| 1303 | If the lane is still running after the timeout expired, there is a chance Lanes will freeze forever at shutdown when failing to terminate all free-running lanes within the specified timeout. | 1294 | If the lane is still running after the timeout expired, there is a chance Lanes will freeze forever at shutdown when failing to terminate all free-running lanes within the specified timeout. |
| 1304 | </p> | 1295 | </p> |
| 1305 | <p> | 1296 | <p> |
| 1306 | Cancellation is tested <u>before</u> going to sleep in <tt>receive()</tt>, <tt>receive_batched()</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. | 1297 | Cancellation is tested <u>before</u> going to sleep in <code>receive()</code>, <code>receive_batched()</code> or <code>send()</code> calls and after executing <code>cancelstep</code> Lua statements. A pending <code>receive()</code>or <code>send()</code> call is awakened. |
| 1307 | <br /> | 1298 | <br /> |
| 1308 | 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). | 1299 | 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). |
| 1309 | <br /> | 1300 | <br /> |
| @@ -1315,10 +1306,10 @@ | |||
| 1315 | false|"soft"|"hard" = cancel_test(true) -- returns "hard" instead of raising | 1306 | false|"soft"|"hard" = cancel_test(true) -- returns "hard" instead of raising |
| 1316 | </pre></td></tr></table> | 1307 | </pre></td></tr></table> |
| 1317 | <p> | 1308 | <p> |
| 1318 | Lanes installs the function <tt>cancel_test()</tt> in each created lane to manually test for cancel requests. | 1309 | Lanes installs the function <code>cancel_test()</code> in each created lane to manually test for cancel requests. |
| 1319 | It returns <tt>false</tt> when no cancel is pending, <tt>"soft"</tt> on a soft cancel request, and raises | 1310 | It returns <code>false</code> when no cancel is pending, <code>"soft"</code> on a soft cancel request, and raises |
| 1320 | <tt>lanes.cancel_error</tt> on a hard cancel request. Passing <tt>true</tt> as the optional argument suppresses | 1311 | <code>lanes.cancel_error</code> on a hard cancel request. Passing <code>true</code> as the optional argument suppresses |
| 1321 | the raise and returns <tt>"hard"</tt> instead, which is useful when the lane needs to distinguish the cancel | 1312 | the raise and returns <code>"hard"</code> instead, which is useful when the lane needs to distinguish the cancel |
| 1322 | mode before deciding how to react. | 1313 | mode before deciding how to react. |
| 1323 | </p> | 1314 | </p> |
| 1324 | 1315 | ||
| @@ -1333,12 +1324,12 @@ | |||
| 1333 | </pre></td></tr></table> | 1324 | </pre></td></tr></table> |
| 1334 | 1325 | ||
| 1335 | <p> | 1326 | <p> |
| 1336 | The regular Lua <tt>error</tt> function is usable in lanes for throwing exceptions. What Lua does not offer, however, is scoped <a href="http://en.wikipedia.org/wiki/Finalizer">finalizers</a> | 1327 | The regular Lua <code>error</code> function is usable in lanes for throwing exceptions. What Lua does not offer, however, is scoped <a href="http://en.wikipedia.org/wiki/Finalizer">finalizers</a> |
| 1337 | that would get called when a certain block of instructions gets exited, whether through peaceful return or abrupt <tt>error</tt>. | 1328 | that would get called when a certain block of instructions gets exited, whether through peaceful return or abrupt <code>error</code>. |
| 1338 | </p> | 1329 | </p> |
| 1339 | 1330 | ||
| 1340 | <p> | 1331 | <p> |
| 1341 | Lanes registers a function <tt>set_finalizer()</tt> in the lane's Lua state for doing this. | 1332 | Lanes registers a function <code>set_finalizer()</code> in the lane's Lua state for doing this. |
| 1342 | Any functions given to it will be called in the lane's Lua state, just prior to closing it. It is possible to set more than one finalizer. They are called in LIFO order. | 1333 | Any functions given to it will be called in the lane's Lua state, just prior to closing it. It is possible to set more than one finalizer. They are called in LIFO order. |
| 1343 | </p> | 1334 | </p> |
| 1344 | 1335 | ||
| @@ -1413,23 +1404,23 @@ | |||
| 1413 | <li>Values can be any type supported by inter-state copying (same <a href="#limitations">limits</a> as for function arguments and upvalues).</li> | 1404 | <li>Values can be any type supported by inter-state copying (same <a href="#limitations">limits</a> as for function arguments and upvalues).</li> |
| 1414 | <li> | 1405 | <li> |
| 1415 | Registered functions and userdata transiting into a Keeper state are converted to a special dummy closure that holds its actual identity. On transit out, the identity is used to find the real function or userdata in the destination. | 1406 | Registered functions and userdata transiting into a Keeper state are converted to a special dummy closure that holds its actual identity. On transit out, the identity is used to find the real function or userdata in the destination. |
| 1416 | For that reason, it is not possible to run user code inside a Keeper state. The only exception is <a href="#on_state_create"><tt>on_state_create</tt></a>, which is handled in a special way. | 1407 | For that reason, it is not possible to run user code inside a Keeper state. The only exception is <a href="#on_state_create"><code>on_state_create</code></a>, which is handled in a special way. |
| 1417 | </li> | 1408 | </li> |
| 1418 | <li>Consuming method is <tt>:receive()</tt> (not in).</li> | 1409 | <li>Consuming method is <code>:receive()</code> (not in).</li> |
| 1419 | <li>Non-consuming method is <tt>:get()</tt> (not rd).</li> | 1410 | <li>Non-consuming method is <code>:get()</code> (not rd).</li> |
| 1420 | <li>Two producer-side methods: <tt>:send()</tt> and <tt>:set()</tt> (not out).</li> | 1411 | <li>Two producer-side methods: <code>:send()</code> and <code>:set()</code> (not out).</li> |
| 1421 | <li><tt>send()</tt> allows for sending multiple values -atomically- to a given slot.</li> | 1412 | <li><code>send()</code> allows for sending multiple values -atomically- to a given slot.</li> |
| 1422 | <li><tt>receive()</tt> can wait for multiple slots at once.</li> | 1413 | <li><code>receive()</code> can wait for multiple slots at once.</li> |
| 1423 | <li><tt>receive_batched()</tt> can be used to consume more than one value from a single slot, as in <tt>linda:receive_batched(1.0, "slot", 3, 6).</tt></li> | 1414 | <li><code>receive_batched()</code> can be used to consume more than one value from a single slot, as in <code>linda:receive_batched(1.0, "slot", 3, 6).</code></li> |
| 1424 | <li><tt>restrict()</tt> can restrain a particular slot to function either with <tt>send()/receive()</tt> or <tt>set()/get()</tt>.</li> | 1415 | <li><code>restrict()</code> can restrain a particular slot to function either with <code>send()/receive()</code> or <code>set()/get()</code>.</li> |
| 1425 | <li>Individual slots' queue length can be limited, balancing speed differences in a producer/consumer scenario (making <tt>:send()</tt> wait).</li> | 1416 | <li>Individual slots' queue length can be limited, balancing speed differences in a producer/consumer scenario (making <code>:send()</code> wait).</li> |
| 1426 | <li><tt>tostring(linda)</tt> returns a string of the form <tt>"Linda: <opt_name>"</tt></li> | 1417 | <li><code>tostring(linda)</code> returns a string of the form <code>"Linda: <opt_name>"</code></li> |
| 1427 | <li> | 1418 | <li> |
| 1428 | 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>). | 1419 | 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 <code>[0,nb_user_keepers]</code>). |
| 1429 | Lanes has an internal linda used for timers and <tt>lanes.wait()</tt>; this linda uses group 0. | 1420 | Lanes has an internal linda used for timers and <code>lanes.wait()</code>; this linda uses group 0. |
| 1430 | </li> | 1421 | </li> |
| 1431 | <li> | 1422 | <li> |
| 1432 | IMPORTANT: *all* linda operations are wrapped inside a <tt>lua_gc STOP/RESTART</tt> pair. | 1423 | IMPORTANT: *all* linda operations are wrapped inside a <code>lua_gc STOP/RESTART</code> pair. |
| 1433 | 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>. | 1424 | 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>. |
| 1434 | </li> | 1425 | </li> |
| 1435 | </ul> | 1426 | </ul> |
| @@ -1440,17 +1431,17 @@ | |||
| 1440 | </pre></td></tr></table> | 1431 | </pre></td></tr></table> |
| 1441 | 1432 | ||
| 1442 | <p> | 1433 | <p> |
| 1443 | Argument to <tt>lanes.linda()</tt> is either <tt>nil</tt> or a single table. The table may contain the following entries: | 1434 | Argument to <code>lanes.linda()</code> is either <code>nil</code> or a single table. The table may contain the following entries: |
| 1444 | <ul> | 1435 | <ul> |
| 1445 | <li><tt>close_handler</tt>: a callable object (function or table/userdata with <tt>__call</tt> metamethod). If provided, and the linda is to-be-closed (Lua 5.4+), it will be called with all the provided arguments. For older Lua versions, its presence is ignored.</li> | 1436 | <li><code>close_handler</code>: a callable object (function or table/userdata with <code>__call</code> metamethod). If provided, and the linda is to-be-closed (Lua 5.4+), it will be called with all the provided arguments. For older Lua versions, its presence is ignored.</li> |
| 1446 | <li><tt>group</tt>: an integer between 0 and the number of <a href="#keepers">Keeper states</a>. Mandatory if Lanes is configured with more than one <a href="#keepers">Keeper state</a>. Group 0 is used by the internal timer linda.</li> | 1437 | <li><code>group</code>: an integer between 0 and the number of <a href="#keepers">Keeper states</a>. Mandatory if Lanes is configured with more than one <a href="#keepers">Keeper state</a>. Group 0 is used by the internal timer linda.</li> |
| 1447 | <li> | 1438 | <li> |
| 1448 | <tt>name</tt>: a string. Converting the linda to a string will yield the provided name prefixed by <tt>"Linda: "</tt>. | 1439 | <code>name</code>: a string. Converting the linda to a string will yield the provided name prefixed by <code>"Linda: "</code>. |
| 1449 | If omitted or empty, it will evaluate to the string representation of a hexadecimal number uniquely representing that linda when the linda is converted to a string. The numeric value is the same as returned by <tt>linda:deep()</tt>.<br /> | 1440 | If omitted or empty, it will evaluate to the string representation of a hexadecimal number uniquely representing that linda when the linda is converted to a string. The numeric value is the same as returned by <code>linda:deep()</code>.<br /> |
| 1450 | If <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>. | 1441 | If <code>"auto"</code>, Lanes will try to construct a name from the source location that called <code>lanes.linda()</code>. If that fails, the linda name will be <code>"<unresolved>"</code>. |
| 1451 | </li> | 1442 | </li> |
| 1452 | <li> | 1443 | <li> |
| 1453 | <tt>wake_period</tt>: a number > 0 (unit: seconds). If provided, overrides <a href="#linda_wake_period"><tt>linda_wake_period</tt></a> provided to <a href="#initialization"><tt>lanes.configure()</tt></a>. | 1444 | <code>wake_period</code>: a number > 0 (unit: seconds). If provided, overrides <a href="#linda_wake_period"><code>linda_wake_period</code></a> provided to <a href="#initialization"><code>lanes.configure()</code></a>. |
| 1454 | </li> | 1445 | </li> |
| 1455 | </ul> | 1446 | </ul> |
| 1456 | Unknown fields are silently ignored. | 1447 | Unknown fields are silently ignored. |
| @@ -1462,12 +1453,12 @@ | |||
| 1462 | </pre></td></tr></table> | 1453 | </pre></td></tr></table> |
| 1463 | 1454 | ||
| 1464 | <p> | 1455 | <p> |
| 1465 | 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 /> | 1456 | By default, queue sizes are unlimited but limits can be enforced using the <code>limit()</code> method. This can be useful to balance execution speeds in a producer/consumer scenario.<br /> |
| 1466 | A limit of 0 is allowed to block everything. <tt>"unlimited"</tt> removes the limit.<br /> | 1457 | A limit of 0 is allowed to block everything. <code>"unlimited"</code> removes the limit.<br /> |
| 1467 | If the slot 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>. | 1458 | If the slot was full but the limit change added some room, <code>limit()</code> first return value is <code>true</code> and the linda is signalled so that <code>send()</code>-blocked threads are awakened, else the return value is <code>false</code>. |
| 1468 | If no limit is provided, <tt>limit()</tt> first return value is the current limit for the specified slot.<br /> | 1459 | If no limit is provided, <code>limit()</code> first return value is the current limit for the specified slot.<br /> |
| 1469 | The second returned value is a string representing the fill status relatively to the slot's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>). | 1460 | The second returned value is a string representing the fill status relatively to the slot's current limit (one of <code>"over"</code>, <code>"under"</code>, <code>"exact"</code>). |
| 1470 | Whether reading or writing, if the linda is cancelled, <tt>limit()</tt> returns <tt>nil, lanes.cancel_error</tt>. | 1461 | Whether reading or writing, if the linda is cancelled, <code>limit()</code> returns <code>nil, lanes.cancel_error</code>. |
| 1471 | </p> | 1462 | </p> |
| 1472 | 1463 | ||
| 1473 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1464 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
| @@ -1476,12 +1467,12 @@ | |||
| 1476 | </pre></td></tr></table> | 1467 | </pre></td></tr></table> |
| 1477 | 1468 | ||
| 1478 | <p> | 1469 | <p> |
| 1479 | It is possible to restrict a particular slot in a Linda to either <tt>send()/receive()</tt> or <tt>set()/get()</tt> operations.<br /> | 1470 | It is possible to restrict a particular slot in a Linda to either <code>send()/receive()</code> or <code>set()/get()</code> operations.<br /> |
| 1480 | Possible modes are <tt>"none"</tt>, <tt>"set/get"</tt> or <tt>"send/receive"</tt>.<br /> | 1471 | Possible modes are <code>"none"</code>, <code>"set/get"</code> or <code>"send/receive"</code>.<br /> |
| 1481 | If a new mode is specified, <tt>restrict()</tt> updates the mode and returns the previous one.<br /> | 1472 | If a new mode is specified, <code>restrict()</code> updates the mode and returns the previous one.<br /> |
| 1482 | If no mode is specified, <tt>restrict()</tt> does nothing and returns the current mode.<br /> | 1473 | If no mode is specified, <code>restrict()</code> does nothing and returns the current mode.<br /> |
| 1483 | If the linda is cancelled, <tt>restrict()</tt> returns <tt>nil, lanes.cancel_error</tt>.<br /> | 1474 | If the linda is cancelled, <code>restrict()</code> returns <code>nil, lanes.cancel_error</code>.<br /> |
| 1484 | If an unknown mode is specified, <tt>restrict()</tt> raises an error. | 1475 | If an unknown mode is specified, <code>restrict()</code> raises an error. |
| 1485 | </p> | 1476 | </p> |
| 1486 | 1477 | ||
| 1487 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1478 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
| @@ -1489,7 +1480,7 @@ | |||
| 1489 | </pre></td></tr></table> | 1480 | </pre></td></tr></table> |
| 1490 | 1481 | ||
| 1491 | <p> | 1482 | <p> |
| 1492 | Timeouts are given in seconds (>= 0, millisecond accuracy) or <tt>nil</tt>. Timeout can be omitted only if the first slot is not a number (then it is equivalent to an infinite duration).<br /> | 1483 | Timeouts are given in seconds (>= 0, millisecond accuracy) or <code>nil</code>. Timeout can be omitted only if the first slot is not a number (then it is equivalent to an infinite duration).<br /> |
| 1493 | Each slot acts as a FIFO queue. There is no limit to the number of slots a linda may contain. Different lindas can have identical slots, which are totally unrelated. | 1484 | Each slot acts as a FIFO queue. There is no limit to the number of slots a linda may contain. Different lindas can have identical slots, which are totally unrelated. |
| 1494 | </p> | 1485 | </p> |
| 1495 | 1486 | ||
| @@ -1499,18 +1490,18 @@ | |||
| 1499 | </p> | 1490 | </p> |
| 1500 | 1491 | ||
| 1501 | <p> | 1492 | <p> |
| 1502 | 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 /> | 1493 | If <code>linda.null</code> or <code>lanes.null</code> is sent as data in a linda, it will be read as a <code>nil</code>.<br /> |
| 1503 | </p> | 1494 | </p> |
| 1504 | 1495 | ||
| 1505 | <p> | 1496 | <p> |
| 1506 | <tt>send()</tt> raises an error if no data is provided after the slot.<br /> | 1497 | <code>send()</code> raises an error if no data is provided after the slot.<br /> |
| 1507 | <tt>send()</tt> raises an error if called when a restriction forbids its use on the provided slot.<br /> | 1498 | <code>send()</code> raises an error if called when a restriction forbids its use on the provided slot.<br /> |
| 1508 | <tt>send()</tt> raises <tt>lanes.cancel_error</tt> if interrupted by a hard cancel request.<br /> | 1499 | <code>send()</code> raises <code>lanes.cancel_error</code> if interrupted by a hard cancel request.<br /> |
| 1509 | <tt>send()</tt> return values can be: | 1500 | <code>send()</code> return values can be: |
| 1510 | <ul> | 1501 | <ul> |
| 1511 | <li><tt>true</tt> on success.</li> | 1502 | <li><code>true</code> on success.</li> |
| 1512 | <li><tt>nil, "timeout"</tt> if the queue limit was met, and the queue did not empty enough during the given duration.</li> | 1503 | <li><code>nil, "timeout"</code> if the queue limit was met, and the queue did not empty enough during the given duration.</li> |
| 1513 | <li><tt>nil, lanes.cancel_error</tt> if interrupted by a soft cancel request.</li> | 1504 | <li><code>nil, lanes.cancel_error</code> if interrupted by a soft cancel request.</li> |
| 1514 | </ul> | 1505 | </ul> |
| 1515 | </p> | 1506 | </p> |
| 1516 | 1507 | ||
| @@ -1521,16 +1512,16 @@ | |||
| 1521 | </pre></td></tr></table> | 1512 | </pre></td></tr></table> |
| 1522 | 1513 | ||
| 1523 | <p> | 1514 | <p> |
| 1524 | <tt>receive()</tt> and <tt>receive_batched()</tt> raise an error if called when a restriction forbids their use on any provided slot.<br /> | 1515 | <code>receive()</code> and <code>receive_batched()</code> raise an error if called when a restriction forbids their use on any provided slot.<br /> |
| 1525 | <tt>receive_batched()</tt> will raise an error if <tt>min_count < 1</tt> or <tt>max_count < min_count</tt>. | 1516 | <code>receive_batched()</code> will raise an error if <code>min_count < 1</code> or <code>max_count < min_count</code>. |
| 1526 | </p> | 1517 | </p> |
| 1527 | 1518 | ||
| 1528 | <p> | 1519 | <p> |
| 1529 | Unbatched <tt>receive()</tt> return values can be: | 1520 | Unbatched <code>receive()</code> return values can be: |
| 1530 | <ul> | 1521 | <ul> |
| 1531 | <li><tt>nil, lanes.cancel_error</tt> if interrupted by a soft cancel request.</li> | 1522 | <li><code>nil, lanes.cancel_error</code> if interrupted by a soft cancel request.</li> |
| 1532 | <li><tt>nil, "timeout"</tt> if nothing was available.</li> | 1523 | <li><code>nil, "timeout"</code> if nothing was available.</li> |
| 1533 | <li>A slot and the value extracted from it. Note that <tt>nil</tt> can be sent and received; the first returned value <tt>slot</tt> will tell it apart from a timeout.</li> | 1524 | <li>A slot and the value extracted from it. Note that <code>nil</code> can be sent and received; the first returned value <code>slot</code> will tell it apart from a timeout.</li> |
| 1534 | </ul> | 1525 | </ul> |
| 1535 | </p> | 1526 | </p> |
| 1536 | 1527 | ||
| @@ -1553,29 +1544,29 @@ | |||
| 1553 | </pre></td></tr></table> | 1544 | </pre></td></tr></table> |
| 1554 | 1545 | ||
| 1555 | <p> | 1546 | <p> |
| 1556 | <tt>set()</tt> and <tt>get()</tt> raise an error if used when a restriction forbids their use on the provided slot.<br /> | 1547 | <code>set()</code> and <code>get()</code> raise an error if used when a restriction forbids their use on the provided slot.<br /> |
| 1557 | Unless a particular slot is constrained with <tt>restrict()</tt>, <tt>get()</tt>/<tt>set()</tt> and <tt>send()</tt>/<tt>receive()</tt> can be used together; reading a slot essentially peeks the next outcoming value of a queue.<br /> | 1548 | Unless a particular slot is constrained with <code>restrict()</code>, <code>get()</code>/<code>set()</code> and <code>send()</code>/<code>receive()</code> can be used together; reading a slot essentially peeks the next outcoming value of a queue.<br /> |
| 1558 | <tt>get()</tt>/<tt>set()</tt> are for accessing a slot without queuing or consuming. They can be used for making shared tables of storage among the lanes.<br /> | 1549 | <code>get()</code>/<code>set()</code> are for accessing a slot without queuing or consuming. They can be used for making shared tables of storage among the lanes.<br /> |
| 1559 | <tt>set()</tt> never blocks because it ignores the limit. It overwrites existing values and clears any possible queued entries.<br /> | 1550 | <code>set()</code> never blocks because it ignores the limit. It overwrites existing values and clears any possible queued entries.<br /> |
| 1560 | </p> | 1551 | </p> |
| 1561 | <p> | 1552 | <p> |
| 1562 | <tt>get()</tt> can read several values at once, and does not block. Return values ares: | 1553 | <code>get()</code> can read several values at once, and does not block. Return values ares: |
| 1563 | <ul> | 1554 | <ul> |
| 1564 | <li><tt>nil, lanes.cancel_error</tt> in case of <a href="#cancelling">cancellation</a>.</li> | 1555 | <li><code>nil, lanes.cancel_error</code> in case of <a href="#cancelling">cancellation</a>.</li> |
| 1565 | <li><tt>number, val...</tt> where number is the actual count of items obtained from the linda (can be 0).</li> | 1556 | <li><code>number, val...</code> where number is the actual count of items obtained from the linda (can be 0).</li> |
| 1566 | </ul> | 1557 | </ul> |
| 1567 | </p> | 1558 | </p> |
| 1568 | <p> | 1559 | <p> |
| 1569 | <tt>set()</tt> can write several values at the specified slot. Writing <tt>nil</tt> values is possible, and clearing the contents at the specified slot is done by not providing any value.<br /> | 1560 | <code>set()</code> can write several values at the specified slot. Writing <code>nil</code> values is possible, and clearing the contents at the specified slot is done by not providing any value.<br /> |
| 1570 | If <tt>set()</tt> actually stores data, the linda is signalled for write, so that <tt>receive()</tt>-blocked Lanes are awakened.<br /> | 1561 | If <code>set()</code> actually stores data, the linda is signalled for write, so that <code>receive()</code>-blocked Lanes are awakened.<br /> |
| 1571 | Clearing the contents of a non-existent slot does not create it!<br /> | 1562 | Clearing the contents of a non-existent slot does not create it!<br /> |
| 1572 | If the slot was full but the new data count of the slot 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 /> | 1563 | If the slot was full but the new data count of the slot after <code>set()</code> is below its limit, <code>set()</code> first return value is <code>true</code> and the linda is also signaled for read, so that <code>send()</code>-blocked Lanes are awakened.<br /> |
| 1573 | If the slot was not already full, nothing additional happens, and <tt>set()</tt> first return value is <tt>false</tt>.<br /> | 1564 | If the slot was not already full, nothing additional happens, and <code>set()</code> first return value is <code>false</code>.<br /> |
| 1574 | The second return value is a string representing the fill status relatively to the slot's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>). | 1565 | The second return value is a string representing the fill status relatively to the slot's current limit (one of <code>"over"</code>, <code>"under"</code>, <code>"exact"</code>). |
| 1575 | </p> | 1566 | </p> |
| 1576 | 1567 | ||
| 1577 | <p> | 1568 | <p> |
| 1578 | Trying to send or receive data through a cancelled linda does nothing and returns <tt>lanes.cancel_error</tt>. | 1569 | Trying to send or receive data through a cancelled linda does nothing and returns <code>lanes.cancel_error</code>. |
| 1579 | </p> | 1570 | </p> |
| 1580 | 1571 | ||
| 1581 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1572 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
| @@ -1583,7 +1574,7 @@ | |||
| 1583 | </pre></td></tr></table> | 1574 | </pre></td></tr></table> |
| 1584 | 1575 | ||
| 1585 | <p> | 1576 | <p> |
| 1586 | Forces a full garbage collect cycle inside the <a href="#keepers">Keeper state</a> assigned to the linda (same as <tt>lua_gc(L, LUA_GCCOLLECT)</tt>).<br /> | 1577 | Forces a full garbage collect cycle inside the <a href="#keepers">Keeper state</a> assigned to the linda (same as <code>lua_gc(L, LUA_GCCOLLECT)</code>).<br /> |
| 1587 | All lindas sharing the same <a href="#keepers">Keeper state</a> will have to wait for the operation to complete before being able to resume regular service.<br /> | 1578 | All lindas sharing the same <a href="#keepers">Keeper state</a> will have to wait for the operation to complete before being able to resume regular service.<br /> |
| 1588 | Can be useful to clean stale storage after some keys are cleaned. | 1579 | Can be useful to clean stale storage after some keys are cleaned. |
| 1589 | </p> | 1580 | </p> |
| @@ -1616,8 +1607,8 @@ | |||
| 1616 | </pre></td></tr></table> | 1607 | </pre></td></tr></table> |
| 1617 | 1608 | ||
| 1618 | <p> | 1609 | <p> |
| 1619 | Returns a table describing the full contents of a linda, or <tt>nil</tt> if the linda wasn't used yet.<br /> | 1610 | Returns a table describing the full contents of a linda, or <code>nil</code> if the linda wasn't used yet.<br /> |
| 1620 | 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. | 1611 | If Decoda support is enabled with <code>HAVE_DECODA_SUPPORT()</code>, the linda metatable contains a <code>__towatch</code> special function that generates a similar table used for debug display. |
| 1621 | </p> | 1612 | </p> |
| 1622 | 1613 | ||
| 1623 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1614 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
| @@ -1626,10 +1617,10 @@ | |||
| 1626 | </pre></td></tr></table> | 1617 | </pre></td></tr></table> |
| 1627 | 1618 | ||
| 1628 | <p> | 1619 | <p> |
| 1629 | <tt>linda:cancel()</tt> signals the linda so that lanes waiting for read, write, or both, wake up. | 1620 | <code>linda:cancel()</code> signals the linda so that lanes waiting for read, write, or both, wake up. |
| 1630 | 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 /> | 1621 | All linda operations (including <code>get()</code> and <code>set()</code>) will return <code>lanes.cancel_error</code> as when the calling lane is <a href="#cancelling">soft-cancelled</a> as long as the linda is marked as cancelled.<br /> |
| 1631 | <tt>"none"</tt> reset the linda's cancel status, but doesn't signal it.<br /> | 1622 | <code>"none"</code> reset the linda's cancel status, but doesn't signal it.<br /> |
| 1632 | <tt>linda.status</tt> reads the current cancel status. | 1623 | <code>linda.status</code> reads the current cancel status. |
| 1633 | If not void, the lane's cancel status overrides the linda's cancel status. | 1624 | If not void, the lane's cancel status overrides the linda's cancel status. |
| 1634 | </p> | 1625 | </p> |
| 1635 | 1626 | ||
| @@ -1658,7 +1649,7 @@ | |||
| 1658 | 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 /> | 1649 | 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 /> |
| 1659 | 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 /> | 1650 | 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 /> |
| 1660 | If the thread is woken but the condition is not yet fulfilled, it goes back to sleep, until the timeout expires.<br /> | 1651 | If the thread is woken but the condition is not yet fulfilled, it goes back to sleep, until the timeout expires.<br /> |
| 1661 | 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 /> | 1652 | When a lane is cancelled, the signal it is waiting on (if any) is signalled. In that case, the linda operation will return <code>lanes.cancel_error</code>.<br /> |
| 1662 | </p> | 1653 | </p> |
| 1663 | 1654 | ||
| 1664 | <p> | 1655 | <p> |
| @@ -1679,7 +1670,7 @@ | |||
| 1679 | 1670 | ||
| 1680 | <li> | 1671 | <li> |
| 1681 | Performance. Changing any slot in a linda causes all pending threads for that linda to be momentarily awakened (at least in the C level). | 1672 | Performance. Changing any slot in a linda causes all pending threads for that linda to be momentarily awakened (at least in the C level). |
| 1682 | 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. | 1673 | This can degrade performance due to unnecessary OS level context switches. The more Keeper states you declared with <a href="#initialization"><code>lanes.configure()</code></a> the less this should be a problem. |
| 1683 | </li> | 1674 | </li> |
| 1684 | </ul> | 1675 | </ul> |
| 1685 | 1676 | ||
| @@ -1700,19 +1691,19 @@ | |||
| 1700 | </pre></td></tr></table> | 1691 | </pre></td></tr></table> |
| 1701 | 1692 | ||
| 1702 | <p> | 1693 | <p> |
| 1703 | Timers are implemented as a lane. They can be enabled by setting "<tt><a href="#with_timers">with_timers</a></tt>" to <tt>true</tt> in <a href="#initialization"><tt>lanes.configure()</tt></a> settings. | 1694 | Timers are implemented as a lane. They can be enabled by setting "<code><a href="#with_timers">with_timers</a></code>" to <code>true</code> in <a href="#initialization"><code>lanes.configure()</code></a> settings. |
| 1704 | </p> | 1695 | </p> |
| 1705 | 1696 | ||
| 1706 | <p> | 1697 | <p> |
| 1707 | Timers can be run once, or in a reoccurring fashion (<tt>period_secs > 0</tt>). The first occurrence can be given either as a date or as a relative delay in seconds. The <tt>date</tt> table is like what <tt>os.date("*t")</tt> returns, in the local time zone. | 1698 | Timers can be run once, or in a reoccurring fashion (<code>period_secs > 0</code>). The first occurrence can be given either as a date or as a relative delay in seconds. The <code>date</code> table is like what <code>os.date("*t")</code> returns, in the local time zone. |
| 1708 | </p> | 1699 | </p> |
| 1709 | 1700 | ||
| 1710 | <p> | 1701 | <p> |
| 1711 | Once a timer expires, the <tt>slot</tt> is set with the current time (in seconds, same offset as <tt>os.time()</tt> but with millisecond accuracy). The slot can be waited upon using the regular <tt><a href="#lindas">linda</a>:receive()</tt> method. | 1702 | Once a timer expires, the <code>slot</code> is set with the current time (in seconds, same offset as <code>os.time()</code> but with millisecond accuracy). The slot can be waited upon using the regular <code><a href="#lindas">linda</a>:receive()</code> method. |
| 1712 | </p> | 1703 | </p> |
| 1713 | 1704 | ||
| 1714 | <p> | 1705 | <p> |
| 1715 | A timer can be stopped simply with <tt>first_secs=0|nil</tt> and no period. | 1706 | A timer can be stopped simply with <code>first_secs=0|nil</code> and no period. |
| 1716 | </p> | 1707 | </p> |
| 1717 | 1708 | ||
| 1718 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> | 1709 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> |
| @@ -1738,25 +1729,25 @@ | |||
| 1738 | end | 1729 | end |
| 1739 | </pre></td></tr></table> | 1730 | </pre></td></tr></table> |
| 1740 | 1731 | ||
| 1741 | <p> | 1732 | <p/> |
| 1742 | NOTE: Timer slots are set, not queued, so missing a beat is possible especially if the timer cycle is extremely small. The slot value can be used to know the actual time passed. | ||
| 1743 | </p> | ||
| 1744 | 1733 | ||
| 1745 | <table> | 1734 | <table> |
| 1746 | <tr> | 1735 | <tr> |
| 1747 | <td valign=top><i><nobr>Design note:</nobr></i></td> | 1736 | <td style="width:10%"><b>NOTE</b>:</td> |
| 1737 | <td style="width:90%">Timer slots are set, not queued, so missing a beat is possible especially if the timer cycle is extremely small. The slot value can be used to know the actual time passed.</td> | ||
| 1738 | </tr> | ||
| 1739 | <tr> | ||
| 1740 | <td><em>Design note:</em></td> | ||
| 1748 | <td> | 1741 | <td> |
| 1749 | <font size="-1"> | 1742 | Having the API as <code>lanes.timer()</code> is intentional. Another alternative would be <code>linda_h:timer()</code> 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. |
| 1750 | 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. | 1743 | A third choice could be abstracting the timers out of <a href="#lindas">linda</a> realm altogether (<code>timer_h = lanes.timer(date|first_secs, period_secs )</code>) but that would mean separate waiting functions for timers, and lindas. |
| 1751 | 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. | ||
| 1752 | Even if a <a href="#lindas">linda</a> object and slot was returned, that slot couldn't be waited upon simultaneously with one's general <a href="#lindas">linda</a> events. | 1744 | Even if a <a href="#lindas">linda</a> object and slot was returned, that slot couldn't be waited upon simultaneously with one's general <a href="#lindas">linda</a> events. |
| 1753 | The current system gives maximum capabilities with minimum API, and any smoothenings can easily be crafted in Lua at the application level. | 1745 | The current system gives maximum capabilities with minimum API, and any smoothenings can easily be crafted in Lua at the application level. |
| 1754 | </font> | ||
| 1755 | </td> | 1746 | </td> |
| 1756 | </tr> | 1747 | </tr> |
| 1757 | </table> | 1748 | </table> |
| 1758 | 1749 | ||
| 1759 | <p></p> | 1750 | <p/> |
| 1760 | 1751 | ||
| 1761 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1752 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
| 1762 | {[{linda, slot, {when [, period]}}[,...]]} = lanes.timers() | 1753 | {[{linda, slot, {when [, period]}}[,...]]} = lanes.timers() |
| @@ -1764,7 +1755,7 @@ | |||
| 1764 | 1755 | ||
| 1765 | <p> | 1756 | <p> |
| 1766 | The full list of active timers can be obtained. Obviously, this is a snapshot, and non-repeating timers might no longer exist by the time the results are inspected.<br /> | 1757 | The full list of active timers can be obtained. Obviously, this is a snapshot, and non-repeating timers might no longer exist by the time the results are inspected.<br /> |
| 1767 | Can return <tt>nil, "timeout"</tt> or <tt>nil, lanes.cancel_error</tt> in case of interruption. | 1758 | Can return <code>nil, "timeout"</code> or <code>nil, lanes.cancel_error</code> in case of interruption. |
| 1768 | </p> | 1759 | </p> |
| 1769 | 1760 | ||
| 1770 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1761 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
| @@ -1773,8 +1764,8 @@ | |||
| 1773 | 1764 | ||
| 1774 | <p> | 1765 | <p> |
| 1775 | 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). | 1766 | 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). |
| 1776 | Passing <tt>nil</tt> or no argument sleeps indefinitely (until <a href="#cancelling">cancellation</a> is received). Passing a non-negative number sleeps for that many seconds.<br /> | 1767 | Passing <code>nil</code> or no argument sleeps indefinitely (until <a href="#cancelling">cancellation</a> is received). Passing a non-negative number sleeps for that many seconds.<br /> |
| 1777 | Return values should always be <tt>nil, "timeout"</tt> (or <tt>nil, lanes.cancel_error</tt> in case of interruption). | 1768 | Return values should always be <code>nil, "timeout"</code> (or <code>nil, lanes.cancel_error</code> in case of interruption). |
| 1778 | </p> | 1769 | </p> |
| 1779 | 1770 | ||
| 1780 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1771 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
| @@ -1790,7 +1781,7 @@ | |||
| 1790 | <h2 id="locks">Locks etc.</h2> | 1781 | <h2 id="locks">Locks etc.</h2> |
| 1791 | 1782 | ||
| 1792 | <p> | 1783 | <p> |
| 1793 | Lanes does not generally require locks or critical sections to be used, at all. If necessary, a limited queue can be used to emulate them. <tt>lanes.lua</tt> offers some sugar to make it easy: | 1784 | Lanes does not generally require locks or critical sections to be used, at all. If necessary, a limited queue can be used to emulate them. <code>lanes.lua</code> offers some sugar to make it easy: |
| 1794 | </p> | 1785 | </p> |
| 1795 | 1786 | ||
| 1796 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1787 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
| @@ -1802,11 +1793,11 @@ | |||
| 1802 | </pre></td></tr></table> | 1793 | </pre></td></tr></table> |
| 1803 | 1794 | ||
| 1804 | <p> | 1795 | <p> |
| 1805 | 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). | 1796 | 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 <code>M=N=1</code> for a critical section lock (only one lane allowed to enter). |
| 1806 | <br /> | 1797 | <br /> |
| 1807 | When passing <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). | 1798 | When passing <code>"try"</code> as second argument when acquiring, then <code>lock_func</code> operates on the <a href="#lindas">linda</a> with a timeout of 0 to emulate a TryLock() operation. If locking fails, <code>lock_func</code> returns <code>false</code>. <code>"try"</code> is ignored when releasing (as it it not expected to ever have to wait unless the acquisition/release pairs are not properly matched). |
| 1808 | <br /> | 1799 | <br /> |
| 1809 | Upon successful lock/unlock, <tt>lock_func</tt> returns <tt>true</tt> (always the case when block-waiting for completion). | 1800 | Upon successful lock/unlock, <code>lock_func</code> returns <code>true</code> (always the case when block-waiting for completion). |
| 1810 | </p> | 1801 | </p> |
| 1811 | 1802 | ||
| 1812 | <p> | 1803 | <p> |
| @@ -1826,7 +1817,7 @@ | |||
| 1826 | </pre></td></tr></table> | 1817 | </pre></td></tr></table> |
| 1827 | 1818 | ||
| 1828 | <p> | 1819 | <p> |
| 1829 | Each time called, the generated function will change <tt>linda[slot]</tt> atomically, without other lanes being able to interfere. The new value is returned. You can use either <tt>diff 0.0</tt> or <tt>get</tt> to just read the current value. | 1820 | Each time called, the generated function will change <code>linda[slot]</code> atomically, without other lanes being able to interfere. The new value is returned. You can use either <code>diff 0.0</code> or <code>get</code> to just read the current value. |
| 1830 | </p> | 1821 | </p> |
| 1831 | 1822 | ||
| 1832 | <p> | 1823 | <p> |
| @@ -1851,14 +1842,14 @@ | |||
| 1851 | 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 slots). | 1842 | 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 slots). |
| 1852 | </li> | 1843 | </li> |
| 1853 | <li> | 1844 | <li> |
| 1854 | For tables and full userdata that are neither deep nor clonable: before anything else, a converter is searched for in the <tt>__lanesconvert</tt> field of its metatable. | 1845 | For tables and full userdata that are neither deep nor clonable: before anything else, a converter is searched for in the <code>__lanesconvert</code> field of its metatable. |
| 1855 | If there is no metatable, or no <tt>__lanesconvert</tt>, <a href="#convert_fallback"><tt>convert_fallback</tt></a> is used instead. | 1846 | If there is no metatable, or no <code>__lanesconvert</code>, <a href="#convert_fallback"><code>convert_fallback</code></a> is used instead. |
| 1856 | The source object is then converted depending on the converter value: | 1847 | The source object is then converted depending on the converter value: |
| 1857 | <ul> | 1848 | <ul> |
| 1858 | <li><tt>nil</tt>: The value is not converted. If it is not a clonable or deep userdata, the transfer will eventually fail with an error.</li> | 1849 | <li><code>nil</code>: The value is not converted. If it is not a clonable or deep userdata, the transfer will eventually fail with an error.</li> |
| 1859 | <li><tt>lanes.null</tt>: The value is converted to <tt>nil</tt>.</li> | 1850 | <li><code>lanes.null</code>: The value is converted to <code>nil</code>.</li> |
| 1860 | <li><tt>"decay"</tt>: The value is converted to a light userdata obtained from <tt>lua_topointer()</tt>.</li> | 1851 | <li><code>"decay"</code>: The value is converted to a light userdata obtained from <code>lua_topointer()</code>.</li> |
| 1861 | <li>A function: The function is called as <tt>o:__lanesconvert(string)</tt>, where the argument is either <tt>"keeper"</tt> (sending data in a Linda) or <tt>"regular"</tt> (when creating or calling a Lane generator). Its first return value is the result of the conversion, the rest is ignored. Transfer is then attempted on the new value. If this also requires a conversion, it will be done, up to a count of <a href="#convert_max_attempts"><tt>convert_max_attempts</tt></a>, after which an error will be raised.</li> | 1852 | <li>A function: The function is called as <code>o:__lanesconvert(string)</code>, where the argument is either <code>"keeper"</code> (sending data in a Linda) or <code>"regular"</code> (when creating or calling a Lane generator). Its first return value is the result of the conversion, the rest is ignored. Transfer is then attempted on the new value. If this also requires a conversion, it will be done, up to a count of <a href="#convert_max_attempts"><code>convert_max_attempts</code></a>, after which an error will be raised.</li> |
| 1862 | <li>Any other value raises an error.</li> | 1853 | <li>Any other value raises an error.</li> |
| 1863 | </ul> | 1854 | </ul> |
| 1864 | </li> | 1855 | </li> |
| @@ -1869,10 +1860,10 @@ | |||
| 1869 | Objects (tables with a metatable) are copyable between lanes. Metatables are assumed to be immutable; they are internally indexed and only copied once per each type of objects per lane. | 1860 | Objects (tables with a metatable) are copyable between lanes. Metatables are assumed to be immutable; they are internally indexed and only copied once per each type of objects per lane. |
| 1870 | </li> | 1861 | </li> |
| 1871 | <li> | 1862 | <li> |
| 1872 | C functions (<tt>lua_CFunction</tt>) referring to <tt>LUA_ENVIRONINDEX</tt> or <tt>LUA_REGISTRYINDEX</tt> might not do what you expect in the target, since they will actually use a different environment. | 1863 | C functions (<code>lua_CFunction</code>) referring to <code>LUA_ENVIRONINDEX</code> or <code>LUA_REGISTRYINDEX</code> might not do what you expect in the target, since they will actually use a different environment. |
| 1873 | </li> | 1864 | </li> |
| 1874 | <li> | 1865 | <li> |
| 1875 | Lua 5.2 functions may have a special <tt>_ENV</tt> upvalue if they perform 'global namespace' lookups. Unless special care is taken, this upvalue defaults to the table found at <tt>LUA_RIDX_GLOBALS</tt>. | 1866 | Lua 5.2 functions may have a special <code>_ENV</code> upvalue if they perform 'global namespace' lookups. Unless special care is taken, this upvalue defaults to the table found at <code>LUA_RIDX_GLOBALS</code>. |
| 1876 | Obviously, we don't want to transfer the whole global table along with each Lua function. Therefore, any upvalue equal to the global table is not transfered by value, but simply bound | 1867 | Obviously, we don't want to transfer the whole global table along with each Lua function. Therefore, any upvalue equal to the global table is not transfered by value, but simply bound |
| 1877 | to the global table in the destination state. Note that this also applies when Lanes is built for Lua 5.1, as it doesn't hurt. | 1868 | to the global table in the destination state. Note that this also applies when Lanes is built for Lua 5.1, as it doesn't hurt. |
| 1878 | </li> | 1869 | </li> |
| @@ -1904,9 +1895,9 @@ | |||
| 1904 | <p> | 1895 | <p> |
| 1905 | Since functions and full userdata are first class values, they don't have a name. All we know for sure is that when a C module registers some functions or full userdata, they are accessible to the script that required the module through some exposed variables. | 1896 | Since functions and full userdata are first class values, they don't have a name. All we know for sure is that when a C module registers some functions or full userdata, they are accessible to the script that required the module through some exposed variables. |
| 1906 | <br /> | 1897 | <br /> |
| 1907 | For example, loading the <tt>string</tt> base library creates a table accessible when indexing the global environment with key <tt>"string"</tt>. Indexing this table with <tt>"match"</tt>, <tt>"gsub"</tt>, etc. will give us a function. | 1898 | For example, loading the <code>string</code> base library creates a table accessible when indexing the global environment with key <code>"string"</code>. Indexing this table with <code>"match"</code>, <code>"gsub"</code>, etc. will give us a function. |
| 1908 | <br /> | 1899 | <br /> |
| 1909 | Similarly, loading the <tt>io</tt> base library creates a table accessible when indexing the global environment with key <tt>"io"</tt>. Indexing this table with <tt>"open"</tt>, will give us a function, and <tt>"stdin"</tt> will give us a full userdata. | 1900 | Similarly, loading the <code>io</code> base library creates a table accessible when indexing the global environment with key <code>"io"</code>. Indexing this table with <code>"open"</code>, will give us a function, and <code>"stdin"</code> will give us a full userdata. |
| 1910 | <br /> | 1901 | <br /> |
| 1911 | When a lane generator creates a lane and performs initializations described by the list of base libraries and the list of required modules, it recursively scans the table created by the initialisation of the module, looking for all values that are C functions and full userdata. | 1902 | When a lane generator creates a lane and performs initializations described by the list of base libraries and the list of required modules, it recursively scans the table created by the initialisation of the module, looking for all values that are C functions and full userdata. |
| 1912 | <br /> | 1903 | <br /> |
| @@ -1914,25 +1905,25 @@ | |||
| 1914 | <br /> | 1905 | <br /> |
| 1915 | Then, when a function or full userdata is transfered from one state to another, all we have to do is retrieve the name associated to this value in the source Lua state, then with that name retrieve the equivalent value that already exists in the destination state. | 1906 | Then, when a function or full userdata is transfered from one state to another, all we have to do is retrieve the name associated to this value in the source Lua state, then with that name retrieve the equivalent value that already exists in the destination state. |
| 1916 | <br /> | 1907 | <br /> |
| 1917 | Note that there is no need to transfer upvalues/uservalues, as they are already bound to the value registered in the destination state. (And in any event, it is not possible to create a closure from a C function pushed on the stack, it can only be created with a <tt>lua_CFunction</tt> pointer). | 1908 | Note that there is no need to transfer upvalues/uservalues, as they are already bound to the value registered in the destination state. (And in any event, it is not possible to create a closure from a C function pushed on the stack, it can only be created with a <code>lua_CFunction</code> pointer). |
| 1918 | </p> | 1909 | </p> |
| 1919 | 1910 | ||
| 1920 | <p> | 1911 | <p> |
| 1921 | There are several issues here: | 1912 | There are several issues here: |
| 1922 | <ul> | 1913 | <ul> |
| 1923 | <li> | 1914 | <li> |
| 1924 | Some base libraries register some C functions in the global environment. Because of that, Lanes must scan the global namespace to find all C functions (such as <tt>error</tt>, <tt>print</tt>, <tt>require</tt>, etc.).<br /> | 1915 | Some base libraries register some C functions in the global environment. Because of that, Lanes must scan the global namespace to find all C functions (such as <code>error</code>, <code>print</code>, <code>require</code>, etc.).<br /> |
| 1925 | This happens a single time, when <a href="#initialization"><tt>lanes.configure()</tt></a> is called. Therefore, if some base libraries are not loaded before that point, it will not be possible to send values that reference stuff they offer unless they are manually registered with <tt>lanes.register()</tt>. | 1916 | This happens a single time, when <a href="#initialization"><code>lanes.configure()</code></a> is called. Therefore, if some base libraries are not loaded before that point, it will not be possible to send values that reference stuff they offer unless they are manually registered with <code>lanes.register()</code>. |
| 1926 | </li> | 1917 | </li> |
| 1927 | <li> | 1918 | <li> |
| 1928 | Nothing prevents a script to create other references to a C function or full userdata. For example one could do | 1919 | Nothing prevents a script to create other references to a C function or full userdata. For example one could do |
| 1929 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> | 1920 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> |
| 1930 | string2 = string | 1921 | string2 = string |
| 1931 | </pre></td></tr></table> | 1922 | </pre></td></tr></table> |
| 1932 | When iterating over all keys of the global table, Lanes has no guarantee that it will hit <tt>"string"</tt> before or after <tt>"string2"</tt>. However, the values associated to <tt>string.match</tt> and <tt>string2.match</tt> are the same C function. | 1923 | When iterating over all keys of the global table, Lanes has no guarantee that it will hit <code>"string"</code> before or after <code>"string2"</code>. However, the values associated to <code>string.match</code> and <code>string2.match</code> are the same C function. |
| 1933 | Lanes doesn't normally expect a C function or full userdata value to be encountered more than once. In the event it occurs, the shortest name that was computed is retained. | 1924 | Lanes doesn't normally expect a C function or full userdata value to be encountered more than once. In the event it occurs, the shortest name that was computed is retained. |
| 1934 | If Lanes processed <tt>"string2"</tt> first, it means that if the Lua state that contains the <tt>"string2"</tt> global name sends function <tt>string.match</tt>, <tt>lookup_func_name</tt> would return name <tt>"string2.match"</tt>, with the obvious effect that <tt>push_resolved_func</tt> | 1925 | If Lanes processed <code>"string2"</code> first, it means that if the Lua state that contains the <code>"string2"</code> global name sends function <code>string.match</code>, <code>lookup_func_name</code> would return name <code>"string2.match"</code>, with the obvious effect that <code>push_resolved_func</code> |
| 1935 | won't find <tt>"string2.match"</tt> in the destination lookup database, thus failing the transfer (even though this function exists, but is referenced under name <tt>"string.match"</tt>). | 1926 | won't find <code>"string2.match"</code> in the destination lookup database, thus failing the transfer (even though this function exists, but is referenced under name <code>"string.match"</code>). |
| 1936 | </li> | 1927 | </li> |
| 1937 | <li> | 1928 | <li> |
| 1938 | Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order on different VMs even when the tables are populated the exact same way. | 1929 | Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order on different VMs even when the tables are populated the exact same way. |
| @@ -1944,14 +1935,14 @@ | |||
| 1944 | </ul> | 1935 | </ul> |
| 1945 | Another more immediate reason of failed transfer is when the destination state doesn't know about the C function or full userdata that has to be transferred. This occurs if a value is transferred in a lane before it had a chance to scan the module that exposed it. | 1936 | Another more immediate reason of failed transfer is when the destination state doesn't know about the C function or full userdata that has to be transferred. This occurs if a value is transferred in a lane before it had a chance to scan the module that exposed it. |
| 1946 | If the C function or full userdata is sent through a <a href="#lindas">linda</a>, it is sufficient for the destination lane body to have required the module before the function is sent. | 1937 | If the C function or full userdata is sent through a <a href="#lindas">linda</a>, it is sufficient for the destination lane body to have required the module before the function is sent. |
| 1947 | But if the lane body provided to the generator has a C function or full userdata as upvalue, the transfer itself must succeed, therefore the module that exposed that C function or full userdata 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. | 1938 | But if the lane body provided to the generator has a C function or full userdata as upvalue, the transfer itself must succeed, therefore the module that exposed that C function or full userdata must be required in the destination lane before the lane body starts executing. This is where the <a href = "#.required"><code>.required</code></a> options play their role. |
| 1948 | </p> | 1939 | </p> |
| 1949 | 1940 | ||
| 1950 | 1941 | ||
| 1951 | <h3>Required of module makers</h3> | 1942 | <h3>Required of module makers</h3> |
| 1952 | 1943 | ||
| 1953 | <p> | 1944 | <p> |
| 1954 | Most Lua extension modules should work unaltered with Lanes. If the module simply ties C side features to Lua, everything is fine without alterations. The <tt>luaopen_...()</tt> entry point will be called separately for each lane, where the module is <tt>require</tt>'d from. | 1945 | Most Lua extension modules should work unaltered with Lanes. If the module simply ties C side features to Lua, everything is fine without alterations. The <code>luaopen_...()</code> entry point will be called separately for each lane, where the module is <code>require</code>'d from. |
| 1955 | </p> | 1946 | </p> |
| 1956 | 1947 | ||
| 1957 | <p> | 1948 | <p> |
| @@ -1974,9 +1965,9 @@ | |||
| 1974 | 1965 | ||
| 1975 | <h3 id="clonable_userdata">Clonable full userdata in your own apps</h3> | 1966 | <h3 id="clonable_userdata">Clonable full userdata in your own apps</h3> |
| 1976 | <p> | 1967 | <p> |
| 1977 | An alternative way of passing full userdata across lanes uses a new <tt>__lanesclone</tt> metamethod. | 1968 | An alternative way of passing full userdata across lanes uses a new <code>__lanesclone</code> metamethod. |
| 1978 | When a deep userdata is cloned, Lanes calls <tt>__lanesclone</tt> once, in the context of the source lane.<br /> | 1969 | When a deep userdata is cloned, Lanes calls <code>__lanesclone</code> once, in the context of the source lane.<br /> |
| 1979 | The call receives the clone and original as light userdata, plus the actual userdata size, as in <tt>clone:__lanesclone(original,size)</tt>, and should perform the actual cloning.<br /> | 1970 | The call receives the clone and original as light userdata, plus the actual userdata size, as in <code>clone:__lanesclone(original,size)</code>, and should perform the actual cloning.<br /> |
| 1980 | A typical implementation would look like: | 1971 | A typical implementation would look like: |
| 1981 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> | 1972 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> |
| 1982 | static int clonable_lanesclone(lua_State* L) | 1973 | static int clonable_lanesclone(lua_State* L) |
| @@ -2002,7 +1993,7 @@ static int clonable_lanesclone(lua_State* L) | |||
| 2002 | 1993 | ||
| 2003 | <p> | 1994 | <p> |
| 2004 | <b>NOTE</b>: In the event the source userdata has uservalues, it is not necessary to create them for the clone, Lanes will handle their cloning.<br /> | 1995 | <b>NOTE</b>: In the event the source userdata has uservalues, it is not necessary to create them for the clone, Lanes will handle their cloning.<br /> |
| 2005 | Of course, more complex objects may require smarter cloning behavior than a simple <tt>memcpy</tt>. Also, the module initialisation code should make each metatable accessible from the module table itself as in: | 1996 | Of course, more complex objects may require smarter cloning behavior than a simple <code>memcpy</code>. Also, the module initialisation code should make each metatable accessible from the module table itself as in: |
| 2006 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> | 1997 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> |
| 2007 | int luaopen_deep_userdata_example(lua_State* L) | 1998 | int luaopen_deep_userdata_example(lua_State* L) |
| 2008 | { | 1999 | { |
| @@ -2029,7 +2020,7 @@ int luaopen_deep_userdata_example(lua_State* L) | |||
| 2029 | </p> | 2020 | </p> |
| 2030 | 2021 | ||
| 2031 | <p> | 2022 | <p> |
| 2032 | Then a new clonable userdata instance can just do like any non-Lanes aware userdata, as long as its metatable contains the aforementionned <tt>__lanesclone</tt> method. | 2023 | Then a new clonable userdata instance can just do like any non-Lanes aware userdata, as long as its metatable contains the aforementionned <code>__lanesclone</code> method. |
| 2033 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> | 2024 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> |
| 2034 | int luaD_new_clonable(lua_State* L) | 2025 | int luaD_new_clonable(lua_State* L) |
| 2035 | { | 2026 | { |
| @@ -2063,30 +2054,30 @@ class MyDeepFactory : public DeepFactory | |||
| 2063 | static MyDeepFactory g_MyDeepFactory; | 2054 | static MyDeepFactory g_MyDeepFactory; |
| 2064 | </pre></td></tr></table> | 2055 | </pre></td></tr></table> |
| 2065 | <ul> | 2056 | <ul> |
| 2066 | <li><tt>newDeepObjectInternal()</tt>: requests the creation of a new object, whose pointer is returned. Said object must derive from <tt>DeepPrelude</tt>.</li> | 2057 | <li><code>newDeepObjectInternal()</code>: requests the creation of a new object, whose pointer is returned. Said object must derive from <code>DeepPrelude</code>.</li> |
| 2067 | <li><tt>deleteDeepObjectInternal()</tt>: should cleanup the object.</li> | 2058 | <li><code>deleteDeepObjectInternal()</code>: should cleanup the object.</li> |
| 2068 | <li><tt>createMetatable()</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<tt>createMetatable</tt> should only be invoked once per state). Just push the metatable on the stack.</li> | 2059 | <li><code>createMetatable()</code>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<code>createMetatable</code> should only be invoked once per state). Just push the metatable on the stack.</li> |
| 2069 | <li><tt>moduleName()</tt>: requests the name of the module that exports the factory, to be returned. It is necessary so that Lanes can require it in any lane state that receives a userdata. This is to prevent crashes in situations where the module could be unloaded while the factory pointer is still held.</li> | 2060 | <li><code>moduleName()</code>: requests the name of the module that exports the factory, to be returned. It is necessary so that Lanes can require it in any lane state that receives a userdata. This is to prevent crashes in situations where the module could be unloaded while the factory pointer is still held.</li> |
| 2070 | </ul> | 2061 | </ul> |
| 2071 | Take a look at <tt>LindaFactory</tt> in <tt>lindafactory.cpp</tt> or <tt>MyDeepFactory</tt> in <tt>deep_userdata_example.cpp</tt>. | 2062 | Take a look at <code>LindaFactory</code> in <code>lindafactory.cpp</code> or <code>MyDeepFactory</code> in <code>deep_userdata_example.cpp</code>. |
| 2072 | </li> | 2063 | </li> |
| 2073 | <li>Include <tt>"_pch.hpp", "deep.hpp"</tt> and either link against Lanes or statically compile <tt>compat.cpp deep.cpp</tt> into your module if you want to avoid a runtime dependency for users that will use your module without Lanes. | 2064 | <li>Include <code>"_pch.hpp", "deep.hpp"</code> and either link against Lanes or statically compile <code>compat.cpp deep.cpp</code> into your module if you want to avoid a runtime dependency for users that will use your module without Lanes. |
| 2074 | <li>Instanciate your userdata using <tt>yourFactoryObject.pushDeepUserdata()</tt>, instead of the regular <tt>lua_newuserdata()</tt>. Given a <tt>factory</tt>, it sets up the support structures and returns a state-specific proxy full userdata for accessing your data. This proxy can also be copied over to other lanes.</li> | 2065 | <li>Instanciate your userdata using <code>yourFactoryObject.pushDeepUserdata()</code>, instead of the regular <code>lua_newuserdata()</code>. Given a <code>factory</code>, it sets up the support structures and returns a state-specific proxy full userdata for accessing your data. This proxy can also be copied over to other lanes.</li> |
| 2075 | <li>Accessing the deep userdata from your C code, use <tt>yourFactoryObject.toDeep()</tt> instead of the regular <tt>lua_touserdata()</tt>.</li> | 2066 | <li>Accessing the deep userdata from your C code, use <code>yourFactoryObject.toDeep()</code> instead of the regular <code>lua_touserdata()</code>.</li> |
| 2076 | <li>To push an existing proxy on the stack, use <tt>DeepPrelude::push(L)</tt>.</li> | 2067 | <li>To push an existing proxy on the stack, use <code>DeepPrelude::push(L)</code>.</li> |
| 2077 | </ol> | 2068 | </ol> |
| 2078 | 2069 | ||
| 2079 | <p> | 2070 | <p> |
| 2080 | Deep userdata management will take care of tying to <tt>__gc</tt> methods, and doing reference counting to see how many proxies are still there for accessing the data. Once there are none, the data will be freed through a call to the factory you provided. | 2071 | Deep userdata management will take care of tying to <code>__gc</code> methods, and doing reference counting to see how many proxies are still there for accessing the data. Once there are none, the data will be freed through a call to the factory you provided. |
| 2081 | </p> | 2072 | </p> |
| 2082 | 2073 | ||
| 2083 | <p> | 2074 | <p> |
| 2084 | Pay attention to the fact a deep userdata last proxy can be held inside a <a href="#keepers">Keeper state</a> after being stored in a <a href="#lindas">linda</a> and all other references are lost. | 2075 | Pay attention to the fact a deep userdata last proxy can be held inside a <a href="#keepers">Keeper state</a> after being stored in a <a href="#lindas">linda</a> and all other references are lost. |
| 2085 | If the <a href="#lindas">linda</a> then flushes its contents through garbage collection in the <a href="#keepers">Keeper state</a> or by being collected itself, it means that <tt>deleteDeepObjectInternal()</tt> can be called from inside a <a href="#keepers">Keeper state</a>. | 2076 | If the <a href="#lindas">linda</a> then flushes its contents through garbage collection in the <a href="#keepers">Keeper state</a> or by being collected itself, it means that <code>deleteDeepObjectInternal()</code> can be called from inside a <a href="#keepers">Keeper state</a>. |
| 2086 | </p> | 2077 | </p> |
| 2087 | 2078 | ||
| 2088 | <p> | 2079 | <p> |
| 2089 | <b>NOTE</b>: The lifespan of deep userdata may exceed that of the Lua state that created it. The allocation of the data storage should not be tied to the Lua state used. In other words, use <tt>new</tt>/<tt>delete</tt>, <tt>malloc()</tt>/<tt>free()</tt> or similar memory handling mechanism. | 2080 | <b>NOTE</b>: The lifespan of deep userdata may exceed that of the Lua state that created it. The allocation of the data storage should not be tied to the Lua state used. In other words, use <code>new</code>/<code>delete</code>, <code>malloc()</code>/<code>free()</code> or similar memory handling mechanism. |
| 2090 | </p> | 2081 | </p> |
| 2091 | 2082 | ||
| 2092 | 2083 | ||
| @@ -2104,7 +2095,7 @@ static MyDeepFactory g_MyDeepFactory; | |||
| 2104 | <h3>Beware with print and file output</h3> | 2095 | <h3>Beware with print and file output</h3> |
| 2105 | 2096 | ||
| 2106 | <p> | 2097 | <p> |
| 2107 | In multithreaded scenarios, giving multiple arguments to <tt>print()</tt> or <tt>file:write()</tt> may cause them to be overlapped in the output, something like this: | 2098 | In multithreaded scenarios, giving multiple arguments to <code>print()</code> or <code>file:write()</code> may cause them to be overlapped in the output, something like this: |
| 2108 | 2099 | ||
| 2109 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> | 2100 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> |
| 2110 | A: print(1, 2, 3, 4 ) | 2101 | A: print(1, 2, 3, 4 ) |
| @@ -2128,9 +2119,9 @@ static MyDeepFactory g_MyDeepFactory; | |||
| 2128 | <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> | 2119 | <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> |
| 2129 | <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> | 2120 | <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> |
| 2130 | <li>Waiting lindas are woken up (and execute some hidden Lua code) each time <u>any</u> slot 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> slots are used. Using separate <a href="#lindas">lindas</a> for logically separate issues will help (which is good practice anyhow).</li> | 2121 | <li>Waiting lindas are woken up (and execute some hidden Lua code) each time <u>any</u> slot 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> slots are used. Using separate <a href="#lindas">lindas</a> for logically separate issues will help (which is good practice anyhow).</li> |
| 2131 | <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> | 2122 | <li><a href="#lindas">linda</a> objects are light. The memory footprint is two OS-level signalling objects (<code>HANDLE</code> or <code>pthread_cond_t</code>) for each, plus one C pointer for the proxies per each Lua state using the <a href="#lindas">linda</a>. Barely nothing.</li> |
| 2132 | <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> | 2123 | <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 <code>timer.lua</code>); no OS side timers are utilized.</li> |
| 2133 | <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> | 2124 | <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"><code>lanes.configure()</code></a>).</li> |
| 2134 | </ul> | 2125 | </ul> |
| 2135 | </p> | 2126 | </p> |
| 2136 | 2127 | ||
| @@ -2139,7 +2130,7 @@ static MyDeepFactory g_MyDeepFactory; | |||
| 2139 | 2130 | ||
| 2140 | <p> | 2131 | <p> |
| 2141 | <a href="#cancelling">Cancellation</a> of lanes uses the Lua error mechanism with a special lightuserdata error sentinel. | 2132 | <a href="#cancelling">Cancellation</a> of lanes uses the Lua error mechanism with a special lightuserdata error sentinel. |
| 2142 | 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. | 2133 | If you use <code>pcall</code> 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. |
| 2143 | You should throw any lightuserdata error further. | 2134 | You should throw any lightuserdata error further. |
| 2144 | </p> | 2135 | </p> |
| 2145 | 2136 | ||
| @@ -2148,7 +2139,7 @@ static MyDeepFactory g_MyDeepFactory; | |||
| 2148 | </p> | 2139 | </p> |
| 2149 | 2140 | ||
| 2150 | <p> | 2141 | <p> |
| 2151 | The sentinel is exposed as <tt>lanes.cancel_error</tt>, if you wish to use its actual value. | 2142 | The sentinel is exposed as <code>lanes.cancel_error</code>, if you wish to use its actual value. |
| 2152 | </p> | 2143 | </p> |
| 2153 | 2144 | ||
| 2154 | 2145 | ||
diff --git a/docs/lua.css b/docs/lua.css new file mode 100644 index 0000000..9013b44 --- /dev/null +++ b/docs/lua.css | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | html { | ||
| 2 | background-color: #F8F8F8 ; | ||
| 3 | } | ||
| 4 | |||
| 5 | body { | ||
| 6 | background-color: #FFFFFF ; | ||
| 7 | color: #000000 ; | ||
| 8 | font-family: Helvetica, Arial, sans-serif ; | ||
| 9 | text-align: justify ; | ||
| 10 | line-height: 1.25 ; | ||
| 11 | margin: 16px auto ; | ||
| 12 | padding: 32px ; | ||
| 13 | border: solid #ccc 1px ; | ||
| 14 | border-radius: 20px ; | ||
| 15 | max-width: 70em ; | ||
| 16 | width: 90% ; | ||
| 17 | } | ||
| 18 | |||
| 19 | h1, h2, h3, h4 { | ||
| 20 | color: #000080 ; | ||
| 21 | font-family: Verdana, Geneva, sans-serif ; | ||
| 22 | font-weight: normal ; | ||
| 23 | font-style: normal ; | ||
| 24 | text-align: left ; | ||
| 25 | } | ||
| 26 | |||
| 27 | h1 { | ||
| 28 | font-size: 28pt ; | ||
| 29 | } | ||
| 30 | |||
| 31 | h1 img { | ||
| 32 | vertical-align: text-bottom ; | ||
| 33 | } | ||
| 34 | |||
| 35 | h2:before { | ||
| 36 | content: "\2756" ; | ||
| 37 | padding-right: 0.5em ; | ||
| 38 | } | ||
| 39 | |||
| 40 | a { | ||
| 41 | text-decoration: none ; | ||
| 42 | } | ||
| 43 | |||
| 44 | a:link { | ||
| 45 | color: #000080 ; | ||
| 46 | } | ||
| 47 | |||
| 48 | a:link:hover, a:visited:hover { | ||
| 49 | background-color: #D0D0FF ; | ||
| 50 | color: #000080 ; | ||
| 51 | border-radius: 4px ; | ||
| 52 | } | ||
| 53 | |||
| 54 | a:link:active, a:visited:active { | ||
| 55 | color: #FF0000 ; | ||
| 56 | } | ||
| 57 | |||
| 58 | div.menubar { | ||
| 59 | padding-bottom: 0.5em ; | ||
| 60 | } | ||
| 61 | |||
| 62 | p.menubar { | ||
| 63 | margin-left: 2.5em ; | ||
| 64 | } | ||
| 65 | |||
| 66 | .menubar a:hover { | ||
| 67 | margin: -3px -3px -3px -3px ; | ||
| 68 | padding: 3px 3px 3px 3px ; | ||
| 69 | border-radius: 4px ; | ||
| 70 | } | ||
| 71 | |||
| 72 | :target { | ||
| 73 | background-color: #F0F0F0 ; | ||
| 74 | margin: -8px ; | ||
| 75 | padding: 8px ; | ||
| 76 | border-radius: 8px ; | ||
| 77 | outline: none ; | ||
| 78 | } | ||
| 79 | |||
| 80 | hr { | ||
| 81 | display: none ; | ||
| 82 | } | ||
| 83 | |||
| 84 | table hr { | ||
| 85 | background-color: #a0a0a0 ; | ||
| 86 | color: #a0a0a0 ; | ||
| 87 | border: 0 ; | ||
| 88 | height: 1px ; | ||
| 89 | display: block ; | ||
| 90 | } | ||
| 91 | |||
| 92 | .footer { | ||
| 93 | color: gray ; | ||
| 94 | font-size: x-small ; | ||
| 95 | text-transform: lowercase ; | ||
| 96 | } | ||
| 97 | |||
| 98 | input[type=text] { | ||
| 99 | border: solid #a0a0a0 2px ; | ||
| 100 | border-radius: 2em ; | ||
| 101 | background-image: url('images/search.png') ; | ||
| 102 | background-repeat: no-repeat ; | ||
| 103 | background-position: 4px center ; | ||
| 104 | padding-left: 20px ; | ||
| 105 | height: 2em ; | ||
| 106 | } | ||
| 107 | |||
| 108 | pre.session { | ||
| 109 | background-color: #F8F8F8 ; | ||
| 110 | padding: 1em ; | ||
| 111 | border-radius: 8px ; | ||
| 112 | } | ||
| 113 | |||
| 114 | table { | ||
| 115 | border: none ; | ||
| 116 | border-spacing: 0 ; | ||
| 117 | border-collapse: collapse ; | ||
| 118 | } | ||
| 119 | |||
| 120 | td { | ||
| 121 | padding: 0 ; | ||
| 122 | margin: 0 ; | ||
| 123 | } | ||
| 124 | |||
| 125 | td.gutter { | ||
| 126 | width: 4% ; | ||
| 127 | } | ||
| 128 | |||
| 129 | table.columns td { | ||
| 130 | vertical-align: top ; | ||
| 131 | padding-bottom: 1em ; | ||
| 132 | text-align: justify ; | ||
| 133 | line-height: 1.25 ; | ||
| 134 | } | ||
| 135 | |||
| 136 | table.book td { | ||
| 137 | vertical-align: top ; | ||
| 138 | } | ||
| 139 | |||
| 140 | table.book td.cover { | ||
| 141 | padding-right: 1em ; | ||
| 142 | } | ||
| 143 | |||
| 144 | table.book img { | ||
| 145 | border: solid #000080 1px ; | ||
| 146 | border-radius: 2px ; | ||
| 147 | } | ||
| 148 | |||
| 149 | table.book span { | ||
| 150 | font-size: small ; | ||
| 151 | text-align: left ; | ||
| 152 | display: block ; | ||
| 153 | margin-top: 0.25em ; | ||
| 154 | } | ||
| 155 | |||
| 156 | p.logos a:link:hover, p.logos a:visited:hover { | ||
| 157 | background-color: inherit ; | ||
| 158 | } | ||
| 159 | |||
| 160 | img { | ||
| 161 | background-color: white ; | ||
| 162 | } | ||
diff --git a/docs/manual.css b/docs/manual.css new file mode 100644 index 0000000..aa0e677 --- /dev/null +++ b/docs/manual.css | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | h3 code { | ||
| 2 | font-family: inherit ; | ||
| 3 | font-size: inherit ; | ||
| 4 | } | ||
| 5 | |||
| 6 | pre, code { | ||
| 7 | font-size: 12pt ; | ||
| 8 | } | ||
| 9 | |||
| 10 | span.apii { | ||
| 11 | color: gray ; | ||
| 12 | float: right ; | ||
| 13 | font-family: inherit ; | ||
| 14 | font-style: normal ; | ||
| 15 | font-size: small ; | ||
| 16 | } | ||
| 17 | |||
| 18 | h2:before { | ||
| 19 | content: "" ; | ||
| 20 | padding-right: 0em ; | ||
| 21 | } | ||
