aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--docs/index.html231
-rw-r--r--src/lanes.lua2
-rw-r--r--tests/appendud.lua1
-rw-r--r--tests/atomic.lua1
-rw-r--r--tests/basic.lua5
-rw-r--r--tests/cyclic.lua1
-rw-r--r--tests/deadlock.lua49
-rw-r--r--tests/ehynes.lua1
-rw-r--r--tests/fibonacci.lua2
-rw-r--r--tests/hangtest.lua1
-rw-r--r--tests/irayo_closure.lua1
-rw-r--r--tests/irayo_recursive.lua2
-rw-r--r--tests/launchtest.lua1
-rw-r--r--tests/objects.lua1
-rw-r--r--tests/parallel_os_calls.lua2
-rw-r--r--tests/pingpong.lua2
-rw-r--r--tests/recursive.lua8
17 files changed, 151 insertions, 160 deletions
diff --git a/docs/index.html b/docs/index.html
index 73753d7..5f9a0fb 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -63,9 +63,9 @@
63 63
64 <font size="-1"> 64 <font size="-1">
65 <p> 65 <p>
66 <br/> 66 <br />
67 <i>Copyright &copy; 2007-24 Asko Kauppi, Benoit Germain. All rights reserved.</i> 67 <i>Copyright &copy; 2007-24 Asko Kauppi, Benoit Germain. All rights reserved.</i>
68 <br/> 68 <br />
69 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 and 5.4. 69 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 and 5.4.
70 </p> 70 </p>
71 71
@@ -184,7 +184,7 @@
184</table> 184</table>
185<p> 185<p>
186 <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. 186 <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.
187 <br/> 187 <br />
188 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>. 188 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>.
189</p> 189</p>
190 190
@@ -197,17 +197,17 @@
197 <tr> 197 <tr>
198 <td> 198 <td>
199 <pre> #include "lanes.h"</pre> 199 <pre> #include "lanes.h"</pre>
200 <br/> 200 <br />
201 <pre> int load_lanes_lua(lua_State* L)</pre> 201 <pre> int load_lanes_lua(lua_State* L)</pre>
202 <pre> {</pre> 202 <pre> {</pre>
203 <pre> // retrieve lanes.lua from wherever it is stored and return the result of its execution</pre> 203 <pre> // retrieve lanes.lua from wherever it is stored and return the result of its execution</pre>
204 <pre> // trivial example 1:</pre> 204 <pre> // trivial example 1:</pre>
205 <pre> luaL_dofile(L, "lanes.lua");</pre> 205 <pre> luaL_dofile(L, "lanes.lua");</pre>
206 <br/> 206 <br />
207 <pre> // trivial example 2:</pre> 207 <pre> // trivial example 2:</pre>
208 <pre> luaL_dostring(L, bin2c_lanes_lua);</pre> 208 <pre> luaL_dostring(L, bin2c_lanes_lua);</pre>
209 <pre> }</pre> 209 <pre> }</pre>
210 <br/> 210 <br />
211 <pre> void embed_lanes(lua_State* L)</pre> 211 <pre> void embed_lanes(lua_State* L)</pre>
212 <pre> {</pre> 212 <pre> {</pre>
213 <pre> // we need base libraries for Lanes for work</pre> 213 <pre> // we need base libraries for Lanes for work</pre>
@@ -219,7 +219,7 @@
219 <pre> // another example with a custom loader</pre> 219 <pre> // another example with a custom loader</pre>
220 <pre> luaopen_lanes_embedded(L, load_lanes_lua);</pre> 220 <pre> luaopen_lanes_embedded(L, load_lanes_lua);</pre>
221 <pre> lua_pop(L, 1);</pre> 221 <pre> lua_pop(L, 1);</pre>
222 <br/> 222 <br />
223 <pre> // a little test to make sure things work as expected</pre> 223 <pre> // a little test to make sure things work as expected</pre>
224 <pre> luaL_dostring(L, "local lanes = require 'lanes'.configure{with_timers = false}; local l = lanes.linda()");</pre> 224 <pre> luaL_dostring(L, "local lanes = require 'lanes'.configure{with_timers = false}; local l = lanes.linda()");</pre>
225 <pre> }</pre> 225 <pre> }</pre>
@@ -240,26 +240,25 @@
240<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> 240<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
241 <tr> 241 <tr>
242 <td> 242 <td>
243 <pre> local lanes = require "lanes".configure()</pre> 243 <pre> local lanes = require "lanes".configure(options|nil)</pre>
244 </td> 244 </td>
245 </tr> 245 </tr>
246</table> 246</table>
247 247
248<p> 248<p>
249 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/> 249 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 />
250 Lanes needs <tt>"base"</tt>, <tt>"string"</tt> and <tt>"table"</tt> to be initialized beforehand (plus <tt>"jit"</tt> for LuaJIT). 250 Lanes needs <tt>"base"</tt>, <tt>"string"</tt> and <tt>"table"</tt> to be initialized beforehand (plus <tt>"jit"</tt> for LuaJIT).
251</p> 251</p>
252<p> 252<p>
253 After lanes is required, it is necessary 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/> 253 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 />
254 At the same time, <tt>lanes.configure()</tt> itself will be replaced by another function that raises an error if called again with differing arguments, if any. 254 If <tt>lanes.configure()</tt> is not called before starting to use Lanes, it will be called automatically for you with default settings.<br />
255 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 />
256 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.
255</p> 257</p>
256<p> 258<p>
257 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. 259 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.
258 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. 260 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.
259</p> 261</p>
260<p>
261 <b>IMPORTANT NOTE:</b> 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.
262</p>
263 262
264<p> 263<p>
265 <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> 264 <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
@@ -285,8 +284,8 @@
285 </td> 284 </td>
286 <td>integer in [0,100]</td> 285 <td>integer in [0,100]</td>
287 <td> 286 <td>
288 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/> 287 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 />
289 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/> 288 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 />
290 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. 289 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.
291 </td> 290 </td>
292 </tr> 291 </tr>
@@ -297,8 +296,8 @@
297 </td> 296 </td>
298 <td>integer</td> 297 <td>integer</td>
299 <td> 298 <td>
300 If &lt;0, GC runs automatically. This is the default.<br/> 299 If &lt;0, GC runs automatically. This is the default.<br />
301 If 0, GC runs after *every* <a href="#keepers">Keeper</a> operation.<br/> 300 If 0, GC runs after *every* <a href="#keepers">Keeper</a> operation.<br />
302 If &gt;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. 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. 301 If &gt;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. 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.
303 </td> 302 </td>
304 </tr> 303 </tr>
@@ -337,8 +336,8 @@
337 <tt>nil</tt>/<tt>"protected"</tt>/function 336 <tt>nil</tt>/<tt>"protected"</tt>/function
338 </td> 337 </td>
339 <td> 338 <td>
340 If <tt>nil</tt>, Lua states are created with <tt>lua_newstate()</tt> and reuse the allocator from the master state.<br/> 339 If <tt>nil</tt>, Lua states are created with <tt>lua_newstate()</tt> and reuse the allocator from the master state.<br />
341 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/> 340 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 />
342 If a <tt>function</tt>, this function is called prior to creating the state. It should return a full userdata containing the following structure: 341 If a <tt>function</tt>, this function is called prior to creating the state. It should return a full userdata containing the following structure:
343 <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> 342 <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
344 <tr> 343 <tr>
@@ -361,8 +360,8 @@
361 </td> 360 </td>
362 <td> 361 <td>
363 Controls which allocator is used for Lanes internal allocations (for <a href="#keepers">Keeper state</a>, <a href="#lindas">Linda</a> and lane management). 362 Controls which allocator is used for Lanes internal allocations (for <a href="#keepers">Keeper state</a>, <a href="#lindas">Linda</a> and lane management).
364 If <tt>"libc"</tt>, Lanes uses <tt>realloc</tt> and <tt>free</tt>.<br/> 363 If <tt>"libc"</tt>, Lanes uses <tt>realloc</tt> and <tt>free</tt>.<br />
365 If <tt>"allocator"</tt>, Lanes uses whatever was obtained from the <tt>"allocator"</tt> setting.<br/> 364 If <tt>"allocator"</tt>, Lanes uses whatever was obtained from the <tt>"allocator"</tt> setting.<br />
366 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). 365 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).
367 </td> 366 </td>
368 </tr> 367 </tr>
@@ -388,16 +387,16 @@
388 function/<tt>nil</tt> 387 function/<tt>nil</tt>
389 </td> 388 </td>
390 <td> 389 <td>
391 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/> 390 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 />
392 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/> 391 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 />
393 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/> 392 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 />
394 Typical usage is twofold: 393 Typical usage is twofold:
395 <ul> 394 <ul>
396 <li>Tweak <tt>package.loaders</tt></li> 395 <li>Tweak <tt>package.loaders</tt></li>
397 <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li> 396 <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li>
398 </ul> 397 </ul>
399 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/> 398 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 />
400 If <tt>on_state_create()</tt> is a Lua function, it will be transfered normally before the call.<br/> 399 If <tt>on_state_create()</tt> is a Lua function, it will be transfered normally before the call.<br />
401 </td> 400 </td>
402 </tr> 401 </tr>
403 402
@@ -439,9 +438,9 @@
439 438
440<p> 439<p>
441 Once Lanes is configured, one should register with Lanes the modules exporting functions that will be transferred either during lane generation or through <a href="#lindas">lindas</a>. 440 Once Lanes is configured, one should register with Lanes the modules exporting functions that will be transferred either during lane generation or through <a href="#lindas">lindas</a>.
442 <br/> 441 <br />
443 Use <tt>lanes.require()</tt> for this purpose. This will call the original <tt>require()</tt>, then add the result to the lookup databases. 442 Use <tt>lanes.require()</tt> for this purpose. This will call the original <tt>require()</tt>, then add the result to the lookup databases.
444 <br/> 443 <br />
445 It is also possible to register a given module with <tt>lanes.register()</tt>. This function will raise an error if the registered module is not a function or table. 444 It is also possible to register a given module with <tt>lanes.register()</tt>. This function will raise an error if the registered module is not a function or table.
446</p> 445</p>
447 446
@@ -469,9 +468,9 @@
469</p> 468</p>
470 469
471<p> 470<p>
472 An error will be raised if you attempt to do this from inside a lane, or on bad arguments (non-function, or too many arguments).<br/> 471 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 />
473 Only the last registered finalizer is kept. It can be cleared by passing <tt>nil</tt> or nothing.<br/> 472 Only the last registered finalizer is kept. It can be cleared by passing <tt>nil</tt> or nothing.<br />
474 The installed function is called after all free-running lanes are terminated, but before lindas become unusable.<br/> 473 The installed function is called after all free-running lanes are terminated, but before lindas become unusable.<br />
475 If an error occurs inside this finalizer, it is silently swallowed, since it happens only during state shutdown, and you can't do anything about it. 474 If an error occurs inside this finalizer, it is silently swallowed, since it happens only during state shutdown, and you can't do anything about it.
476</p> 475</p>
477 476
@@ -485,17 +484,17 @@
485<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> 484<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
486 <tr> 485 <tr>
487 <td> 486 <td>
488 <pre> local lanes = require "lanes".configure()</pre> 487 <pre> local lanes = require "lanes"</pre>
489 <br/> 488 <br />
490 <pre> f = lanes.gen(function(n) return 2 * n end)</pre> 489 <pre> f = lanes.gen(function(n) return 2 * n end)</pre>
491 <pre> a = f(1)</pre> 490 <pre> a = f(1)</pre>
492 <pre> b = f(2)</pre> 491 <pre> b = f(2)</pre>
493 <br/> 492 <br />
494 <pre> print(a[1], b[1]) -- 2 4</pre> 493 <pre> print(a[1], b[1]) -- 2 4</pre>
495 </td> 494 </td>
496 </tr> 495 </tr>
497</table> 496</table>
498<br/> 497<br />
499<table border=1 bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> 498<table border=1 bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
500 <tr> 499 <tr>
501 <td> 500 <td>
@@ -507,7 +506,7 @@
507 506
508<p> 507<p>
509 The function returned by <tt>lanes.gen()</tt> is a "generator" for launching any number of lanes. They will share code, options, initial globals, but the particular arguments may vary. Only calling the generator function actually launches a lane, and provides a handle for controlling it. 508 The function returned by <tt>lanes.gen()</tt> is a "generator" for launching any number of lanes. They will share code, options, initial globals, but the particular arguments may vary. Only calling the generator function actually launches a lane, and provides a handle for controlling it.
510 <br/> 509 <br />
511 Alternatively, <tt>lane_func</tt> may be a string, in which case it will be compiled in the lane. This was to be able to launch lanes with older versions of LuaJIT, which didn't not support <tt>lua_dump</tt>, used internally to transfer functions to the lane. 510 Alternatively, <tt>lane_func</tt> may be a string, in which case it will be compiled in the lane. This was to be able to launch lanes with older versions of LuaJIT, which didn't not support <tt>lua_dump</tt>, used internally to transfer functions to the lane.
512</p> 511</p>
513 512
@@ -680,7 +679,7 @@
680</p> 679</p>
681 680
682<p> 681<p>
683 Any non-<tt>nil</tt> value causes initialization of <tt>"base"</tt> and <tt>"jit"</tt> (the latter only for LuaJIT-based builds).<br/> 682 Any non-<tt>nil</tt> value causes initialization of <tt>"base"</tt> and <tt>"jit"</tt> (the latter only for LuaJIT-based builds).<br />
684 Initializing the standard libs takes a bit of time at each lane invocation. This is the main reason why "no libraries" is the default. 683 Initializing the standard libs takes a bit of time at each lane invocation. This is the main reason why "no libraries" is the default.
685</p> 684</p>
686 685
@@ -702,7 +701,7 @@
702 </td> 701 </td>
703 <td>table</td> 702 <td>table</td>
704 <td> 703 <td>
705 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/> 704 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 />
706 The global values of different lanes are in no manner connected; modifying one will only affect the particular lane. 705 The global values of different lanes are in no manner connected; modifying one will only affect the particular lane.
707 </td> 706 </td>
708 </tr> 707 </tr>
@@ -715,7 +714,7 @@
715 Lists modules that have to be required in order to be able to transfer functions they exposed. Non-Lua functions are <a href="#function_notes">searched in lookup tables</a>. 714 Lists modules that have to be required in order to be able to transfer functions they exposed. Non-Lua functions are <a href="#function_notes">searched in lookup tables</a>.
716 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 lanes function is invoked. 715 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 lanes function is invoked.
717 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. 716 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.
718 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/> 717 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 />
719 ATTEMPTING TO TRANSFER A FUNCTION REGISTERED BY A MODULE NOT LISTED HERE WILL RAISE AN ERROR. 718 ATTEMPTING TO TRANSFER A FUNCTION REGISTERED BY A MODULE NOT LISTED HERE WILL RAISE AN ERROR.
720 </td> 719 </td>
721 </tr> 720 </tr>
@@ -725,8 +724,8 @@
725 </td> 724 </td>
726 <td>string</td> 725 <td>string</td>
727 <td> 726 <td>
728 Sets the error reporting mode. One of <tt>"minimal"</tt> (the default), <tt>"basic"</tt>, <tt>"extended"</tt>.<br/> 727 Sets the error reporting mode. One of <tt>"minimal"</tt> (the default), <tt>"basic"</tt>, <tt>"extended"</tt>.<br />
729 <tt>"minimal"</tt> yields only the location of the error.<br/> 728 <tt>"minimal"</tt> yields only the location of the error.<br />
730 The other 2 yield a full stack trace, with different amounts of data extracted from the debug infos. See <a href="#results">Results</a>. 729 The other 2 yield a full stack trace, with different amounts of data extracted from the debug infos. See <a href="#results">Results</a>.
731 </td> 730 </td>
732 </tr> 731 </tr>
@@ -755,8 +754,8 @@
755 <td>integer</td> 754 <td>integer</td>
756 <td> 755 <td>
757 The priority of lanes generated in the range -3..+3 (default is 0). 756 The priority of lanes generated in the range -3..+3 (default is 0).
758 These values are a mapping over the actual priority range of the underlying implementation.<br/> 757 These values are a mapping over the actual priority range of the underlying implementation.<br />
759 Implementation and dependability of priorities varies by platform. Especially Linux kernel 2.6 is not supporting priorities in user mode.<br/> 758 Implementation and dependability of priorities varies by platform. Especially Linux kernel 2.6 is not supporting priorities in user mode.<br />
760 A lane can also change its own thread priority dynamically with <a href="#priority"><tt>lanes.set_thread_priority()</tt></a>. 759 A lane can also change its own thread priority dynamically with <a href="#priority"><tt>lanes.set_thread_priority()</tt></a>.
761 </td> 760 </td>
762 </tr> 761 </tr>
@@ -766,7 +765,7 @@
766 </td> 765 </td>
767 <td> table</td> 766 <td> table</td>
768 <td> 767 <td>
769 Specifying it when <code>libs_str</code> doesn't cause the <code>package</code> library to be loaded will generate an error.<br/> 768 Specifying it when <code>libs_str</code> doesn't cause the <code>package</code> library to be loaded will generate an error.<br />
770 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. 769 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.
771 </td> 770 </td>
772 </tr> 771 </tr>
@@ -774,14 +773,14 @@
774 773
775<p> 774<p>
776 Each lane gets a global function <tt>set_debug_threadname()</tt> that it can use anytime to do as the name says. 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 /> 775 Each lane gets a global function <tt>set_debug_threadname()</tt> that it can use anytime to do as the name says. 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 />
777 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/> 776 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 />
778 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/> 777 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 />
779 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 /> 778 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 />
780 The lane also has a method <tt>lane:get_debug_threadname()</tt> that gives access to that name from the caller side (returns <tt>"&lt;unnamed&gt;"</tt> if unset, <tt>"&lt;closed&gt;"</tt> if the internal Lua state is closed). 779 The lane also has a method <tt>lane:get_debug_threadname()</tt> that gives access to that name from the caller side (returns <tt>"&lt;unnamed&gt;"</tt> if unset, <tt>"&lt;closed&gt;"</tt> if the internal Lua state is closed).
781</p> 780</p>
782 781
783<p> 782<p>
784 If a lane body pulls a C function imported by a module required before Lanes itself (thus not through a hooked <tt>require</tt>), the lane generator creation will raise an error. 783 If a lane body pulls a C function imported by a module required before Lanes itself (thus not through a hooked <tt>require()</tt>), the lane generator creation will raise an error.
785 The function name it shows 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: 784 The function name it shows 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:
786 785
787 <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> 786 <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
@@ -823,7 +822,7 @@
823 </table> 822 </table>
824<p> 823<p>
825 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. 824 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.
826 <br/> 825 <br />
827 The priority must be in the range <tt>[-3,+3]</tt>. 826 The priority must be in the range <tt>[-3,+3]</tt>.
828</p> 827</p>
829 828
@@ -886,53 +885,53 @@
886 </td> 885 </td>
887 </tr> 886 </tr>
888 <tr> 887 <tr>
889 <td/> 888 <td />
890 <td> 889 <td>
891 <tt> 890 <tt>
892 "running" 891 "running"
893 </tt> 892 </tt>
894 </td> 893 </td>
895 <td/> 894 <td />
896 <td> 895 <td>
897 running, not suspended on a <a href="#lindas">Linda</a> call. 896 running, not suspended on a <a href="#lindas">Linda</a> call.
898 </td> 897 </td>
899 </tr> 898 </tr>
900 <tr> 899 <tr>
901 <td/> 900 <td />
902 <td> 901 <td>
903 <tt>"waiting"</tt> 902 <tt>"waiting"</tt>
904 </td> 903 </td>
905 <td/> 904 <td />
906 <td> 905 <td>
907 waiting at a <a href="#lindas">Linda</a> <tt>:receive()</tt> or <tt>:send()</tt> 906 waiting at a <a href="#lindas">Linda</a> <tt>:receive()</tt> or <tt>:send()</tt>
908 </td> 907 </td>
909 </tr> 908 </tr>
910 <tr> 909 <tr>
911 <td/> 910 <td />
912 <td> 911 <td>
913 <tt>"done"</tt> 912 <tt>"done"</tt>
914 </td> 913 </td>
915 <td/> 914 <td />
916 <td> 915 <td>
917 finished executing (results are ready) 916 finished executing (results are ready)
918 </td> 917 </td>
919 </tr> 918 </tr>
920 <tr> 919 <tr>
921 <td/> 920 <td />
922 <td> 921 <td>
923 <tt>"error"</tt> 922 <tt>"error"</tt>
924 </td> 923 </td>
925 <td/> 924 <td />
926 <td> 925 <td>
927 met an error (reading results will propagate it) 926 met an error (reading results will propagate it)
928 </td> 927 </td>
929 </tr> 928 </tr>
930 <tr> 929 <tr>
931 <td/> 930 <td />
932 <td> 931 <td>
933 <tt>"cancelled"</tt> 932 <tt>"cancelled"</tt>
934 </td> 933 </td>
935 <td/> 934 <td />
936 <td> 935 <td>
937 received <a href="#cancelling">cancellation</a> and finished itself. 936 received <a href="#cancelling">cancellation</a> and finished itself.
938 </td> 937 </td>
@@ -959,7 +958,7 @@
959 958
960<p> 959<p>
961 Only available if lane tracking is enabled by setting <a href="#track_lanes"><tt>track_lanes</tt></a>. 960 Only available if lane tracking is enabled by setting <a href="#track_lanes"><tt>track_lanes</tt></a>.
962 <br/> 961 <br />
963 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. 962 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.
964</p> 963</p>
965 964
@@ -982,7 +981,7 @@
982 981
983<p> 982<p>
984 Makes sure lane has finished, and gives its first (maybe only) return value. Other return values will be available in other <tt>lane_h</tt> indices. 983 Makes sure lane has finished, and gives its first (maybe only) return value. Other return values will be available in other <tt>lane_h</tt> indices.
985 <br/> 984 <br />
986 If the lane ended in an error, it is propagated to master state at this place. 985 If the lane ended in an error, it is propagated to master state at this place.
987</p> 986</p>
988 987
@@ -991,14 +990,14 @@
991</pre></td></tr></table> 990</pre></td></tr></table>
992 991
993<p> 992<p>
994 <tt>timeout</tt> is an optional number &gt= 0 (the default if unspecified).<br/> 993 <tt>timeout</tt> is an optional number &gt= 0 (the default if unspecified).<br />
995 Waits until the lane finishes, or <tt>timeout</tt> seconds have passed.<br/> 994 Waits until the lane finishes, or <tt>timeout</tt> seconds have passed.<br />
996 Unlike in reading the results in table fashion, errors are not propagated.<br/> 995 Unlike in reading the results in table fashion, errors are not propagated.<br />
997 Possible return values are: 996 Possible return values are:
998 <ul> 997 <ul>
999 <li><tt>nil, "timeout"</tt> on timeout.</li> 998 <li><tt>nil, "timeout"</tt> on timeout.</li>
1000 <li> 999 <li>
1001 <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/> 1000 <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 />
1002 <ul> 1001 <ul>
1003 <li><tt>"minimal"</tt>: <tt>stack_tbl</tt> is <tt>nil</tt>.</li> 1002 <li><tt>"minimal"</tt>: <tt>stack_tbl</tt> is <tt>nil</tt>.</li>
1004 <li><tt>"basic"</tt>: <tt>stack_tbl</tt> is an array of <tt>"&lt;filename&gt;:&lt;line&gt;"</tt> strings. You can use <tt>table.concat()</tt> to format it to your liking (or just ignore it).</li> 1003 <li><tt>"basic"</tt>: <tt>stack_tbl</tt> is an array of <tt>"&lt;filename&gt;:&lt;line&gt;"</tt> strings. You can use <tt>table.concat()</tt> to format it to your liking (or just ignore it).</li>
@@ -1012,7 +1011,7 @@
1012</p> 1011</p>
1013 1012
1014<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> 1013<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
1015 local lanes = require "lanes".configure() 1014 local lanes = require "lanes"
1016 1015
1017 f = lanes.gen(function() error "!!!" end) 1016 f = lanes.gen(function() error "!!!" end)
1018 a = f(1) 1017 a = f(1)
@@ -1030,7 +1029,7 @@
1030</p> 1029</p>
1031 1030
1032<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> 1031<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
1033 local lanes = require "lanes".configure() 1032 local lanes = require "lanes"
1034 1033
1035 local sync_linda = lanes.linda() 1034 local sync_linda = lanes.linda()
1036 f = lanes.gen(function() dostuff() sync_linda:send("done", true) end) 1035 f = lanes.gen(function() dostuff() sync_linda:send("done", true) end)
@@ -1053,25 +1052,25 @@
1053 1052
1054<p> 1053<p>
1055 <tt>timeout</tt> is an optional number &gt= 0. Defaults to 0 if left unspecified or <tt>nil</tt>. 1054 <tt>timeout</tt> is an optional number &gt= 0. Defaults to 0 if left unspecified or <tt>nil</tt>.
1056 <br/> 1055 <br />
1057 <tt>cancel()</tt> sends a cancellation request to the lane. 1056 <tt>cancel()</tt> sends a cancellation request to the lane.
1058 <br/> 1057 <br />
1059 First argument is a <tt>mode</tt> can be one of <tt>"hard"</tt>, <tt>"soft"</tt>, <tt>"call"</tt>, <tt>"ret"</tt>, <tt>"line"</tt>, <tt>"count"</tt>. 1058 First argument is a <tt>mode</tt> can be one of <tt>"hard"</tt>, <tt>"soft"</tt>, <tt>"call"</tt>, <tt>"ret"</tt>, <tt>"line"</tt>, <tt>"count"</tt>.
1060 If <tt>mode</tt> is not specified, it defaults to <tt>"hard"</tt>. 1059 If <tt>mode</tt> is not specified, it defaults to <tt>"hard"</tt>.
1061 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>. 1060 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>.
1062</p> 1061</p>
1063<p> 1062<p>
1064 If <tt>mode</tt> is <tt>"soft"</tt>, cancellation will only cause <tt>cancel_test()</tt> to return <tt>true</tt>, so that the lane can cleanup manually.<br/> 1063 If <tt>mode</tt> is <tt>"soft"</tt>, cancellation will only cause <tt>cancel_test()</tt> to return <tt>true</tt>, so that the lane can cleanup manually.<br />
1065</p> 1064</p>
1066<p> 1065<p>
1067 If <tt>mode</tt> is <tt>"hard"</tt>, waits for the request to be processed, or a timeout to occur. <a href="#lindas">Linda</a> operations detecting the cancellation request will raise a special cancellation error (meaning they won't return in that case).<br/> 1066 If <tt>mode</tt> is <tt>"hard"</tt>, waits for the request to be processed, or a timeout to occur. <a href="#lindas">Linda</a> operations detecting the cancellation request will raise a special cancellation error (meaning they won't return in that case).<br />
1068 <tt>wake_lane</tt> defaults to <tt>true</tt>, and <tt>timeout</tt> defaults to 0 if not specified. 1067 <tt>wake_lane</tt> defaults to <tt>true</tt>, and <tt>timeout</tt> defaults to 0 if not specified.
1069</p> 1068</p>
1070<p> 1069<p>
1071 Other values of <tt>mode</tt> will asynchronously install the corresponding hook, then behave as <tt>"hard"</tt>. 1070 Other values of <tt>mode</tt> will asynchronously install the corresponding hook, then behave as <tt>"hard"</tt>.
1072</p> 1071</p>
1073<p> 1072<p>
1074 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/> 1073 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 />
1075 Returns <tt>false, "timeout"</tt> otherwise. 1074 Returns <tt>false, "timeout"</tt> otherwise.
1076</p> 1075</p>
1077<p> 1076<p>
@@ -1079,11 +1078,11 @@
1079</p> 1078</p>
1080<p> 1079<p>
1081 Cancellation is tested <u>before</u> going to sleep in <tt>receive()</tt> or <tt>send()</tt> calls and after executing <tt>cancelstep</tt> Lua statements. A pending <tt>receive()</tt>or <tt>send()</tt> call is awakened. 1080 Cancellation is tested <u>before</u> going to sleep in <tt>receive()</tt> or <tt>send()</tt> calls and after executing <tt>cancelstep</tt> Lua statements. A pending <tt>receive()</tt>or <tt>send()</tt> call is awakened.
1082 <br/> 1081 <br />
1083 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). 1082 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).
1084 <br/> 1083 <br />
1085 The code should be able to handle this situation appropriately if required (in other words, it should gracefully handle the fact that it didn't receive the expected values). 1084 The code should be able to handle this situation appropriately if required (in other words, it should gracefully handle the fact that it didn't receive the expected values).
1086 <br/> 1085 <br />
1087 It is also possible to manually test for cancel requests with <tt>cancel_test()</tt>. 1086 It is also possible to manually test for cancel requests with <tt>cancel_test()</tt>.
1088</p> 1087</p>
1089 1088
@@ -1146,7 +1145,7 @@
1146</p> 1145</p>
1147 1146
1148<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> 1147<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
1149 local lanes = require "lanes".configure() 1148 local lanes = require "lanes"
1150 1149
1151 local linda = lanes.linda("my linda") 1150 local linda = lanes.linda("my linda")
1152 1151
@@ -1201,8 +1200,8 @@
1201</pre></td></tr></table> 1200</pre></td></tr></table>
1202 1201
1203<p> 1202<p>
1204 Converting the Linda to a string will yield the provided name prefixed by <tt>"Linda: "</tt>.<br/> 1203 Converting the Linda to a string will yield the provided name prefixed by <tt>"Linda: "</tt>.<br />
1205 If <tt>opt_name</tt> is omitted, it will evaluate to an hexadecimal number uniquely representing that Linda when the Linda is converted to a string. The value is the same as returned by <tt>linda:deep()</tt>.<br/> 1204 If <tt>opt_name</tt> is omitted, it will evaluate to an hexadecimal number uniquely representing that Linda when the Linda is converted to a string. The value is the same as returned by <tt>linda:deep()</tt>.<br />
1206 If <tt>opt_name</tt> is <tt>"auto"</tt>, Lanes will try to construct a name from the source location that called <tt>lanes.linda()</tt>. If that fails, the Linda name will be <tt>"&lt;unresolved&gt;"</tt>. 1205 If <tt>opt_name</tt> is <tt>"auto"</tt>, Lanes will try to construct a name from the source location that called <tt>lanes.linda()</tt>. If that fails, the Linda name will be <tt>"&lt;unresolved&gt;"</tt>.
1207</p> 1206</p>
1208 1207
@@ -1211,9 +1210,9 @@
1211</pre></td></tr></table> 1210</pre></td></tr></table>
1212 1211
1213<p> 1212<p>
1214 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. <tt>nil</tt> removes the limit.<br/> 1213 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. <tt>nil</tt> removes the limit.<br />
1215 A limit of 0 is allowed to block everything.<br/> 1214 A limit of 0 is allowed to block everything.<br />
1216 If the key was full but the limit change added some room, <tt>limit()</tt> returns <tt>true</tt> and the Linda is signalled so that <tt>send()</tt>-blocked threads are awakened.<br/> 1215 If the key was full but the limit change added some room, <tt>limit()</tt> returns <tt>true</tt> and the Linda is signalled so that <tt>send()</tt>-blocked threads are awakened.<br />
1217</p> 1216</p>
1218 1217
1219<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> 1218<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
@@ -1221,7 +1220,7 @@
1221</pre></td></tr></table> 1220</pre></td></tr></table>
1222 1221
1223<p> 1222<p>
1224 Timeouts are given in seconds (&gt= 0, millisecond accuracy) or <tt>nil</tt>. Timeout can be omitted only if the first key is not a number (then it is equivalent to an infinite duration).<br/> 1223 Timeouts are given in seconds (&gt= 0, millisecond accuracy) or <tt>nil</tt>. Timeout can be omitted only if the first key is not a number (then it is equivalent to an infinite duration).<br />
1225 Each key acts as a FIFO queue. There is no limit to the number of keys a Linda may contain. Different Lindas can have identical keys, which are totally unrelated. 1224 Each key acts as a FIFO queue. There is no limit to the number of keys a Linda may contain. Different Lindas can have identical keys, which are totally unrelated.
1226</p> 1225</p>
1227 1226
@@ -1231,8 +1230,8 @@
1231</p> 1230</p>
1232 1231
1233<p> 1232<p>
1234 If no data is provided after the key, <tt>send()</tt> raises an error.<br/> 1233 If no data is provided after the key, <tt>send()</tt> raises an error.<br />
1235 Also, if <tt>linda.null</tt> or <tt>lanes.null</tt> is sent as data in a Linda, it will be read as a <tt>nil</tt>.<br/> 1234 Also, if <tt>linda.null</tt> or <tt>lanes.null</tt> is sent as data in a Linda, it will be read as a <tt>nil</tt>.<br />
1236 <tt>send()</tt> return values can be: 1235 <tt>send()</tt> return values can be:
1237 <ul> 1236 <ul>
1238 <li><tt>true</tt> on success.</li> 1237 <li><tt>true</tt> on success.</li>
@@ -1280,19 +1279,19 @@
1280</pre></td></tr></table> 1279</pre></td></tr></table>
1281 1280
1282<p> 1281<p>
1283 The table access methods are for accessing a slot without queuing or consuming. They can be used for making shared tables of storage among the lanes.<br/> 1282 The table access methods are for accessing a slot without queuing or consuming. They can be used for making shared tables of storage among the lanes.<br />
1284 Writing to a slot never blocks because it ignores the limit. It overwrites existing value and clears any possible queued entries.<br/> 1283 Writing to a slot never blocks because it ignores the limit. It overwrites existing value and clears any possible queued entries.<br />
1285 Reading doesn't block either because <tt>get()</tt> returns whatever is available (which can be nothing), up to the specified count.<br/> 1284 Reading doesn't block either because <tt>get()</tt> returns whatever is available (which can be nothing), up to the specified count.<br />
1286 Table access and <tt>send()</tt>/<tt>receive()</tt> can be used together; reading a slot essentially peeks the next outcoming value of a queue. 1285 Table access and <tt>send()</tt>/<tt>receive()</tt> can be used together; reading a slot essentially peeks the next outcoming value of a queue.
1287</p> 1286</p>
1288 1287
1289<p> 1288<p>
1290 <tt>set()</tt> signals the Linda for write if a value is stored. If nothing special happens, <tt>set() </tt>returns nothing.<br/> 1289 <tt>set()</tt> signals the Linda for write if a value is stored. If nothing special happens, <tt>set() </tt>returns nothing.<br />
1291 If the key was full but the new data count of the key after <tt>set()</tt> is below its limit, <tt>set()</tt> returns <tt>true</tt> and the Linda is also signaled for read so that <tt>send()</tt>-blocked threads are awakened. 1290 If the key was full but the new data count of the key after <tt>set()</tt> is below its limit, <tt>set()</tt> returns <tt>true</tt> and the Linda is also signaled for read so that <tt>send()</tt>-blocked threads are awakened.
1292</p> 1291</p>
1293 1292
1294<p> 1293<p>
1295 <tt>set()</tt> can write several values at the specified key, writing <tt>nil</tt> values is now possible, and clearing the contents at the specified key is done by not providing any value.<br/> 1294 <tt>set()</tt> can write several values at the specified key, writing <tt>nil</tt> values is now possible, and clearing the contents at the specified key is done by not providing any value.<br />
1296 Also, <tt>get()</tt> can read several values at once. If the key contains no data, <tt>get()</tt> returns no value. This can be used to separate the case when reading stored <tt>nil</tt> values. 1295 Also, <tt>get()</tt> can read several values at once. If the key contains no data, <tt>get()</tt> returns no value. This can be used to separate the case when reading stored <tt>nil</tt> values.
1297</p> 1296</p>
1298 1297
@@ -1305,10 +1304,10 @@
1305</pre></td></tr></table> 1304</pre></td></tr></table>
1306 1305
1307<p> 1306<p>
1308 Returns some information about the contents of the Linda.<br/> 1307 Returns some information about the contents of the Linda.<br />
1309 If no key is specified, and the Linda is empty, returns nothing.<br/> 1308 If no key is specified, and the Linda is empty, returns nothing.<br />
1310 If no key is specified, and the Linda is not empty, returns a table of key/count pairs that counts the number of items in each of the exiting keys of the Linda. This count can be 0 if the key has been used but is empty.<br/> 1309 If no key is specified, and the Linda is not empty, returns a table of key/count pairs that counts the number of items in each of the exiting keys of the Linda. This count can be 0 if the key has been used but is empty.<br />
1311 If a single key is specified, returns the number of pending items, or nothing if the key is unknown.<br/> 1310 If a single key is specified, returns the number of pending items, or nothing if the key is unknown.<br />
1312 If more than one key is specified, return a table of key/count pairs for the known keys. 1311 If more than one key is specified, return a table of key/count pairs for the known keys.
1313</p> 1312</p>
1314 1313
@@ -1317,7 +1316,7 @@
1317</pre></td></tr></table> 1316</pre></td></tr></table>
1318 1317
1319<p> 1318<p>
1320 Returns a table describing the full contents of a Linda, or <tt>nil</tt> if the Linda wasn't used yet.<br/> 1319 Returns a table describing the full contents of a Linda, or <tt>nil</tt> if the Linda wasn't used yet.<br />
1321 If Decoda support is enabled with <tt>HAVE_DECODA_SUPPORT()</tt>, <a Linda metatable contain a <tt>__towatch</tt> special function that generates a similar table used for debug display. 1320 If Decoda support is enabled with <tt>HAVE_DECODA_SUPPORT()</tt>, <a Linda metatable contain a <tt>__towatch</tt> special function that generates a similar table used for debug display.
1322</p> 1321</p>
1323 1322
@@ -1327,8 +1326,8 @@
1327 1326
1328<p> 1327<p>
1329 Signals the Linda so that lanes waiting for read, write, or both, wake up. 1328 Signals the Linda so that lanes waiting for read, write, or both, wake up.
1330 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/> 1329 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 />
1331 <tt>"none"</tt> reset the Linda's cancel status, but doesn't signal it.<br/> 1330 <tt>"none"</tt> reset the Linda's cancel status, but doesn't signal it.<br />
1332 If not void, the lane's cancel status overrides the Linda's cancel status. 1331 If not void, the lane's cancel status overrides the Linda's cancel status.
1333</p> 1332</p>
1334 1333
@@ -1343,12 +1342,12 @@
1343<h3 id="keepers">Granularity of using Lindas</h3> 1342<h3 id="keepers">Granularity of using Lindas</h3>
1344 1343
1345<p> 1344<p>
1346 A Linda is a gateway to read and write data inside some hidden Lua states, called keeper states. Lindas are hashed to a fixed number of keeper states, which are a locking entity.<br/> 1345 A Linda is a gateway to read and write data inside some hidden Lua states, called keeper states. Lindas are hashed to a fixed number of keeper states, which are a locking entity.<br />
1347 The data sent through a Linda is stored inside the associated keeper state in a Lua table where each Linda slot is the key to another table containing a FIFO for that slot.<br/> 1346 The data sent through a Linda is stored inside the associated keeper state in a Lua table where each Linda slot is the key to another table containing a FIFO for that slot.<br />
1348 Each keeper state is associated with an OS mutex, to prevent concurrent access to the keeper state. The Linda itself uses two signals to be made aware of operations occuring on it.<br/> 1347 Each keeper state is associated with an OS mutex, to prevent concurrent access to the keeper state. The Linda itself uses two signals to be made aware of operations occuring on it.<br />
1349 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/> 1348 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 />
1350 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/> 1349 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 />
1351 If the thread is woken but the condition is not yet fulfilled, it goes back to sleep, until the timeout expires.<br/> 1350 If the thread is woken but the condition is not yet fulfilled, it goes back to sleep, until the timeout expires.<br />
1352 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>. 1351 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>.
1353</p> 1352</p>
1354 1353
@@ -1464,7 +1463,7 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1464 1463
1465<p> 1464<p>
1466 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). 1465 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).
1467 Default duration is 0, which should only cause a thread context switch.<br/> 1466 Default duration is 0, which should only cause a thread context switch.<br />
1468 Return values should always be <tt>nil, "timeout"</tt> (or <tt>nil, lanes.cancel_error</tt> in case of interruption). 1467 Return values should always be <tt>nil, "timeout"</tt> (or <tt>nil, lanes.cancel_error</tt> in case of interruption).
1469</p> 1468</p>
1470 1469
@@ -1494,9 +1493,9 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1494 1493
1495<p> 1494<p>
1496 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). 1495 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).
1497 <br/> 1496 <br />
1498 When passsing <tt>"try"</tt> as second argument when acquiring, then <tt>lock_func</tt> operates on the <a href="#lindas">Linda</a> with a timeout of 0 to emulate a TryLock() operation. If locking fails, <tt>lock_func</tt> returns <tt>false</tt>. <tt>"try"</tt> is ignored when releasing (as it it not expected to ever have to wait unless the acquisition/release pairs are not properly matched). 1497 When passsing <tt>"try"</tt> as second argument when acquiring, then <tt>lock_func</tt> operates on the <a href="#lindas">Linda</a> with a timeout of 0 to emulate a TryLock() operation. If locking fails, <tt>lock_func</tt> returns <tt>false</tt>. <tt>"try"</tt> is ignored when releasing (as it it not expected to ever have to wait unless the acquisition/release pairs are not properly matched).
1499 <br/> 1498 <br />
1500 Upon successful lock/unlock, <tt>lock_func</tt> returns <tt>true</tt> (always the case when block-waiting for completion). 1499 Upon successful lock/unlock, <tt>lock_func</tt> returns <tt>true</tt> (always the case when block-waiting for completion).
1501</p> 1500</p>
1502 1501
@@ -1591,15 +1590,15 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1591 1590
1592<p> 1591<p>
1593 Since functions are first class values, they don't have a name. All we know for sure is that when a C module registers some functions, they are accessible to the script that required the module through some exposed variables. 1592 Since functions are first class values, they don't have a name. All we know for sure is that when a C module registers some functions, they are accessible to the script that required the module through some exposed variables.
1594 <br/> 1593 <br />
1595 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. 1594 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.
1596 <br/> 1595 <br />
1597 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. 1596 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.
1598 <br/> 1597 <br />
1599 Each time a function is encountered, the sequence of keys that reached that function is contatenated in a (hopefully) unique name. The [name, function] and [function, name] pairs are both stored in a lookup table in all involved Lua states (main Lua state and lanes states). 1598 Each time a function is encountered, the sequence of keys that reached that function is contatenated in a (hopefully) unique name. The [name, function] and [function, name] pairs are both stored in a lookup table in all involved Lua states (main Lua state and lanes states).
1600 <br/> 1599 <br />
1601 Then when a function is transfered from one state to another, all we have to do is retrieve the name associated to a function in the source Lua state, then with that name retrieve the equivalent function that already exists in the destination state. 1600 Then when a function is transfered from one state to another, all we have to do is retrieve the name associated to a function in the source Lua state, then with that name retrieve the equivalent function that already exists in the destination state.
1602 <br/> 1601 <br />
1603 Note that there is no need to transfer upvalues, as they are already bound to the function 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). 1602 Note that there is no need to transfer upvalues, as they are already bound to the function 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).
1604</p> 1603</p>
1605 1604
@@ -1659,8 +1658,8 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
1659<h3 id="clonable_userdata">Clonable full userdata in your own apps</h3> 1658<h3 id="clonable_userdata">Clonable full userdata in your own apps</h3>
1660<p> 1659<p>
1661 An alternative way of passing full userdata across lanes uses a new <tt>__lanesclone</tt> metamethod. 1660 An alternative way of passing full userdata across lanes uses a new <tt>__lanesclone</tt> metamethod.
1662 When a deep userdata is cloned, Lanes calls <tt>__lanesclone</tt> once, in the context of the source lane.<br/> 1661 When a deep userdata is cloned, Lanes calls <tt>__lanesclone</tt> once, in the context of the source lane.<br />
1663 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/> 1662 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 />
1664 A typical implementation would look like: 1663 A typical implementation would look like:
1665<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> 1664<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
1666static int clonable_lanesclone(lua_State* L) 1665static int clonable_lanesclone(lua_State* L)
@@ -1686,7 +1685,7 @@ static int clonable_lanesclone(lua_State* L)
1686</p> 1685</p>
1687 1686
1688<p> 1687<p>
1689 <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/> 1688 <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 />
1690 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: 1689 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:
1691<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> 1690<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
1692int luaopen_deep_test(lua_State* L) 1691int luaopen_deep_test(lua_State* L)
@@ -1768,9 +1767,9 @@ static MyDeepFactory g_MyDeepFactory;
1768</p> 1767</p>
1769 1768
1770<p> 1769<p>
1771 Deep userdata in transit inside <a href="#keepers">Keeper states</a> (sent in a <a href="#lindas">Linda</a> but not yet consumed) don't call <tt>deleteDeepObjectInternal</tt> and aren't considered by reference counting. The rationale is the following:<br/> 1770 Deep userdata in transit inside <a href="#keepers">Keeper states</a> (sent in a <a href="#lindas">Linda</a> but not yet consumed) don't call <tt>deleteDeepObjectInternal</tt> and aren't considered by reference counting. The rationale is the following:<br />
1772 If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0.<br/> 1771 If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0.<br />
1773 OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's <tt>factory()</tt> interface is never accessed from a keeper state.<br/> 1772 OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's <tt>factory()</tt> interface is never accessed from a keeper state.<br />
1774 Therefore, Lanes can just call <tt>deleteDeepObjectInternal</tt> when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in <a href="#keepers">Keeper states</a> now hold stale pointers. 1773 Therefore, Lanes can just call <tt>deleteDeepObjectInternal</tt> when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in <a href="#keepers">Keeper states</a> now hold stale pointers.
1775</p> 1774</p>
1776 1775
diff --git a/src/lanes.lua b/src/lanes.lua
index 07792b6..d890adf 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -758,7 +758,7 @@ local configure = function(settings_)
758 -- Configure called so remove metatable from lanes 758 -- Configure called so remove metatable from lanes
759 lanesMeta.__metatable = nil -- unprotect the metatable 759 lanesMeta.__metatable = nil -- unprotect the metatable
760 setmetatable(lanes, nil) -- remove it 760 setmetatable(lanes, nil) -- remove it
761 lanes.configure = nil -- no need to call configure() ever again 761 lanes.configure = function() return lanes end -- no need to configure anything again
762 762
763 -- now we can configure Lanes core 763 -- now we can configure Lanes core
764 local settings = core.configure and core.configure(params_checker(settings_)) or core.settings 764 local settings = core.configure and core.configure(params_checker(settings_)) or core.settings
diff --git a/tests/appendud.lua b/tests/appendud.lua
index d0efb26..f510c8b 100644
--- a/tests/appendud.lua
+++ b/tests/appendud.lua
@@ -7,7 +7,6 @@
7-- Needs Lanes >= 2.0.3 7-- Needs Lanes >= 2.0.3
8-- 8--
9local lanes = require "lanes" 9local lanes = require "lanes"
10lanes.configure()
11 10
12local _tab = { 11local _tab = {
13 beginupdate = function (this) print('tab.beginupdate') end; 12 beginupdate = function (this) print('tab.beginupdate') end;
diff --git a/tests/atomic.lua b/tests/atomic.lua
index 12bdf02..2de8f52 100644
--- a/tests/atomic.lua
+++ b/tests/atomic.lua
@@ -5,7 +5,6 @@
5-- 5--
6 6
7local lanes = require "lanes" 7local lanes = require "lanes"
8lanes.configure()
9 8
10local linda= lanes.linda() 9local linda= lanes.linda()
11local key= "$" 10local key= "$"
diff --git a/tests/basic.lua b/tests/basic.lua
index cad3764..bdad44c 100644
--- a/tests/basic.lua
+++ b/tests/basic.lua
@@ -7,7 +7,8 @@
7-- - ... 7-- - ...
8-- 8--
9local config = { with_timers = false, strip_functions = false, internal_allocator = "libc"} 9local config = { with_timers = false, strip_functions = false, internal_allocator = "libc"}
10local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure(config) 10-- calling configure more than once should work (additional called are ignored)
11local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure(config).configure()
11print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2) 12print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2)
12local lanes = require_lanes_result_1 13local lanes = require_lanes_result_1
13 14
@@ -434,7 +435,7 @@ local function chunk2(linda)
434 assert(config.strip_functions and info.short_src=="?" or string.match(info.short_src, "^.*basic.lua$"), "bad info.short_src") 435 assert(config.strip_functions and info.short_src=="?" or string.match(info.short_src, "^.*basic.lua$"), "bad info.short_src")
435 -- These vary so let's not be picky (they're there..) 436 -- These vary so let's not be picky (they're there..)
436 -- 437 --
437 assert(info.linedefined == 419, "bad linedefined") -- start of 'chunk2' 438 assert(info.linedefined == 420, "bad linedefined") -- start of 'chunk2'
438 assert(config.strip_functions and info.currentline==-1 or info.currentline > info.linedefined, "bad currentline") -- line of 'debug.getinfo' 439 assert(config.strip_functions and info.currentline==-1 or info.currentline > info.linedefined, "bad currentline") -- line of 'debug.getinfo'
439 assert(info.lastlinedefined > info.currentline, "bad lastlinedefined") -- end of 'chunk2' 440 assert(info.lastlinedefined > info.currentline, "bad lastlinedefined") -- end of 'chunk2'
440 local k,func= linda:receive("down") 441 local k,func= linda:receive("down")
diff --git a/tests/cyclic.lua b/tests/cyclic.lua
index 553d2a9..fd6d4a0 100644
--- a/tests/cyclic.lua
+++ b/tests/cyclic.lua
@@ -5,7 +5,6 @@
5-- 5--
6 6
7local lanes = require "lanes" 7local lanes = require "lanes"
8lanes.configure()
9 8
10local table_concat= assert(table.concat) 9local table_concat= assert(table.concat)
11 10
diff --git a/tests/deadlock.lua b/tests/deadlock.lua
index c38ca13..bbbda8d 100644
--- a/tests/deadlock.lua
+++ b/tests/deadlock.lua
@@ -1,8 +1,10 @@
1-- this script tests the fix of a bug that could cause the mutex of a keeper state to remain locked 1-- this script tests the fix of a bug that could cause the mutex of a keeper state to remain locked
2-- see https://github.com/LuaLanes/lanes/commit/0cc1c9c9dcea5955f7dab921d9a2fff78c4e1729 2-- see https://github.com/LuaLanes/lanes/commit/0cc1c9c9dcea5955f7dab921d9a2fff78c4e1729
3 3
4local lanes = require('lanes').configure{with_timers=false} 4local lanes = require "lanes"
5local linda = lanes.linda "deadlock_linda" 5
6-- Lua 5.1 compatibility
7local table_unpack = table.unpack or unpack
6 8
7local SLEEP = function(...) 9local SLEEP = function(...)
8 local k, v = lanes.sleep(...) 10 local k, v = lanes.sleep(...)
@@ -14,27 +16,28 @@ print "let's begin"
14local do_extra_stuff = true 16local do_extra_stuff = true
15 17
16if do_extra_stuff then 18if do_extra_stuff then
17 -- just something to make send() succeed and receive() fail (any C function exposed by some module will do) 19 local linda = lanes.linda "deadlock_linda"
18 local payload = { lanes.require('socket').connect } 20 -- just something to make send() succeed and receive() fail
19 21 local payload = { io.flush }
20 -- lane generator 22
21 local g = lanes.gen('*', function() 23 -- lane generator. don't initialize "io" base library so that it is not known in the lane
22 set_debug_threadname( "deadlock_lane") 24 local g = lanes.gen('base,table', function()
23 -- wrapping inside pcall makes the Lanes module unaware that something went wrong 25 set_debug_threadname( "deadlock_lane")
24 print( "In lane 1:", table.unpack{ pcall( linda.receive, linda, 'tmp')}) 26 -- wrapping inside pcall makes the Lanes module unaware that something went wrong
25 -- with the bug not fixed, and non-recursive mutexes, we can hang here 27 print( "In lane 1:", table_unpack{ pcall( linda.receive, linda, 'tmp')})
26 print( "In lane 2:", table.unpack{ pcall( linda.receive, linda, 'tmp')}) 28 -- with the bug not fixed, and non-recursive mutexes, we can hang here
27 -- return something out of the lane 29 print( "In lane 2:", table_unpack{ pcall( linda.receive, linda, 'tmp')})
28 return 33, 55 30 -- return something out of the lane
29 end) 31 return 33, 55
30 32 end)
31 -- send payload twice. succeeds because sending stores a function identification string in the linda's keeper state 33
32 linda:send( 'tmp', payload, payload) 34 -- send payload twice. succeeds because sending stores a function identification string in the linda's keeper state
33 -- start the lane 35 linda:send( 'tmp', payload, payload)
34 local h = g() 36 -- start the lane
35 -- wait for lane completion 37 local h = g()
36 local err, stack = h:join() 38 -- wait for lane completion
37 print( 'result of lane execution', err, stack) 39 local err, stack = h:join()
40 print( 'result of lane execution', err, stack)
38end 41end
39 42
40-- With the bug not fixed, the linda keeper's mutex is still acquired, 43-- With the bug not fixed, the linda keeper's mutex is still acquired,
diff --git a/tests/ehynes.lua b/tests/ehynes.lua
index 9436c7d..cdcd5a5 100644
--- a/tests/ehynes.lua
+++ b/tests/ehynes.lua
@@ -2,7 +2,6 @@
2-- Test from <ehynes at dharmagaia.com> 2-- Test from <ehynes at dharmagaia.com>
3-- 3--
4local lanes = require "lanes" 4local lanes = require "lanes"
5lanes.configure()
6 5
7local SLEEP = function(...) 6local SLEEP = function(...)
8 local k, v = lanes.sleep(...) 7 local k, v = lanes.sleep(...)
diff --git a/tests/fibonacci.lua b/tests/fibonacci.lua
index 0ff2f37..51e7137 100644
--- a/tests/fibonacci.lua
+++ b/tests/fibonacci.lua
@@ -12,7 +12,7 @@
12 12
13-- Need to say it's 'local' so it can be an upvalue 13-- Need to say it's 'local' so it can be an upvalue
14-- 14--
15local lanes = require "lanes".configure() 15local lanes = require "lanes"
16 16
17local function WR(str) 17local function WR(str)
18 io.stderr:write( str.."\n" ) 18 io.stderr:write( str.."\n" )
diff --git a/tests/hangtest.lua b/tests/hangtest.lua
index 6a9f7aa..0e44451 100644
--- a/tests/hangtest.lua
+++ b/tests/hangtest.lua
@@ -3,7 +3,6 @@
3-- 3--
4 4
5local lanes = require "lanes" 5local lanes = require "lanes"
6lanes.configure()
7 6
8local function ret(b) 7local function ret(b)
9 return b 8 return b
diff --git a/tests/irayo_closure.lua b/tests/irayo_closure.lua
index 3278d57..45189ec 100644
--- a/tests/irayo_closure.lua
+++ b/tests/irayo_closure.lua
@@ -11,7 +11,6 @@ e.g. { globals = { data = 1, func = function() useclosurehere() end } }"
11]] 11]]
12 12
13local lanes = require "lanes" 13local lanes = require "lanes"
14lanes.configure()
15 14
16local function testrun() 15local function testrun()
17 assert( print ) 16 assert( print )
diff --git a/tests/irayo_recursive.lua b/tests/irayo_recursive.lua
index fe722a3..88f4aab 100644
--- a/tests/irayo_recursive.lua
+++ b/tests/irayo_recursive.lua
@@ -1,4 +1,4 @@
1local lanes = require "lanes".configure() 1local lanes = require "lanes"
2-- 2--
3-- Bugs filed by irayo Jul-2008 3-- Bugs filed by irayo Jul-2008
4-- 4--
diff --git a/tests/launchtest.lua b/tests/launchtest.lua
index f3a6740..16db242 100644
--- a/tests/launchtest.lua
+++ b/tests/launchtest.lua
@@ -46,7 +46,6 @@ for k,v in pairs( argtable(...) ) do
46end 46end
47 47
48local lanes = require "lanes" 48local lanes = require "lanes"
49lanes.configure()
50 49
51local g= lanes.gen( LIBS, function(i) 50local g= lanes.gen( LIBS, function(i)
52 --io.stderr:write( i.."\t" ) 51 --io.stderr:write( i.."\t" )
diff --git a/tests/objects.lua b/tests/objects.lua
index 7668e45..61c280d 100644
--- a/tests/objects.lua
+++ b/tests/objects.lua
@@ -5,7 +5,6 @@
5-- 5--
6 6
7local lanes = require "lanes" 7local lanes = require "lanes"
8lanes.configure()
9 8
10local linda= lanes.linda() 9local linda= lanes.linda()
11 10
diff --git a/tests/parallel_os_calls.lua b/tests/parallel_os_calls.lua
index 7e7de26..8030d4c 100644
--- a/tests/parallel_os_calls.lua
+++ b/tests/parallel_os_calls.lua
@@ -1,4 +1,4 @@
1local lanes = require "lanes".configure() 1local lanes = require "lanes"
2print( os.date()) 2print( os.date())
3local linda = lanes.linda() 3local linda = lanes.linda()
4local l1 = lanes.gen("os,base", function() print "start sleeping" linda:receive(3, "null") print("finished_sleeping " .. os.date()) return true end)() 4local l1 = lanes.gen("os,base", function() print "start sleeping" linda:receive(3, "null") print("finished_sleeping " .. os.date()) return true end)()
diff --git a/tests/pingpong.lua b/tests/pingpong.lua
index fdc60a6..3498f49 100644
--- a/tests/pingpong.lua
+++ b/tests/pingpong.lua
@@ -1,4 +1,4 @@
1local lanes = require 'lanes'.configure() 1local lanes = require "lanes"
2local q = lanes.linda() 2local q = lanes.linda()
3 3
4local pingpong = function(name, qr, qs, start) 4local pingpong = function(name, qr, qs, start)
diff --git a/tests/recursive.lua b/tests/recursive.lua
index 139f4c8..97b9c5b 100644
--- a/tests/recursive.lua
+++ b/tests/recursive.lua
@@ -12,14 +12,10 @@ local function func( depth )
12 end 12 end
13 13
14 local lanes = require "lanes" 14 local lanes = require "lanes"
15 -- lanes.configure() is available only at the first require() 15 local lane = lanes.gen("*", func)( depth+1 )
16 if lanes.configure then
17 lanes = lanes.configure{with_timers = false}
18 end
19 local lane= lanes.gen("*", func)( depth+1 )
20 return lane[1] 16 return lane[1]
21end 17end
22 18
23local v= func(0) 19local v= func(0)
24assert(v=="done!") 20assert(v=="done!")
25io.stderr:write("\n") 21io.stderr:write("TEST OK\n")