aboutsummaryrefslogtreecommitdiff
path: root/docs/index.html
blob: 28acf3b530433fd638e5c0bbea310bb56b367e2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
	Documentation for Lua Lanes
-->

<html>
<head>
	<meta name="description" content="Lua Lanes - multithreading in Lua" />
	<meta name="keywords" content="Lua, Library, Multithreading, Threads, Rocks" />

	<title>Lua Lanes - multithreading in Lua</title>
</head>

<body>

<div class="header">
	<hr/>

	<center>
		<table summary="Lua logo"><tbody>
			<tr>
				<td align="center">
					<a href="http://www.lua.org">
						<img src="multi.png" alt="Lua" align="middle" border="0" height="120" width="128" />
						<img src="multi.png" alt="Lua" align="middle" border="0" height="120" width="128" />
						<img src="multi.png" alt="Lua" align="middle" border="0" height="120" width="128" />
						<img src="multi.png" alt="Lua" align="middle" border="0" height="120" width="128" />
						<img src="multi.png" alt="Lua" align="middle" border="0" height="120" width="128" />
					</a>
				</td>
			</tr>
			<tr>
				<td align="center" valign="top"><h1>Lua Lanes - multithreading in Lua</h1></td>
			</tr>
		</tbody></table>

		<p class="bar">
			<a href="#description">Description</a> &middot;
			<a href="#systems">Supported systems</a> &middot;
			<a href="#installing">Building and Installing</a> &middot;
			<a href="#embedding">Embedding</a>
		</p>

		<p class="bar">
			<a href="#creation">Creation</a> &middot;
			<a href="#status">Status</a> &middot;
			<a href="#results">Results and errors</a>
		</p>

		<p class="bar">
			<a href="#cancelling">Cancelling</a> &middot;
			<a href="#finalizers">Finalizers</a> &middot;
			<a href="#lindas">Lindas</a> &middot;
			<a href="#timers">Timers</a> &middot;
			<a href="#locks">Locks etc.</a>
		</p>

		<p class="bar">
			<a href="#other">Other issues</a> &middot;
			<a href="#changes">Change log</a>
		</p>
		<!-- ... -->

		<font size="-1">
			<p>
				<br />
				<i>Copyright &copy; 2007-24 Asko Kauppi, Benoit Germain. All rights reserved.</i>
				<br />
				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.
			</p>

			<p>
				This document was revised on 13-Dec-24, and applies to version <tt>4.0.0</tt>.
			</p>
		</font>
	</center>
</div>


<!-- description +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="description">Description</h2>

<p>
	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.
</p>
<p>
	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.
</p>
<p>
	Lanes should build and run identically with either Lua 5.1 to Lua 5.4, as well as LuaJIT.
</p>
<p>
	See <A HREF="comparison.html">comparison</A> of Lua Lanes with other Lua multithreading solutions.
</p>
<p>
	<h3>Features:</h3>

	<ul>
		<li>Lanes have separated data, by default. Shared data is possible with <a href="#lindas">linda</a> objects.</li>
		<li>Communications is separate of threads, using <a href="#lindas">linda</a> objects.</li>
		<li>Data passing uses fast inter-state copies (no serialization required).</li>
		<li>"Deep userdata" concept, for sharing userdata over multiple lanes.</li>
		<li>Millisecond level timers, integrated with the <a href="#lindas">linda</a> system.</li>
		<li>Threads can be given priorities.</li>
		<li>Lanes are cancellable, with proper cleanup.</li>
		<li>No Lua-side application level locking - ever!</li>
		<li>Several totally independant Lanes universes may coexist in an application, one per "master" Lua state.</li>
	</ul>


	<h3 id="limitations">Limitations:</h3>

	<ul>
		<li>Coroutines are not passed between states.</li>
		<li>Sharing full userdata between states needs special C side preparations (-&gt; <A HREF="#deep_userdata">deep userdata</A> and -&gt; <A HREF="#clonable_userdata">clonable userdata</A>).</li>
		<li>Network level parallelism not included.</li>
		<li>Multi-CPU is done with OS threads, not processes. A lane is a Lua full userdata, therefore it will exist only as long as the Lua state that created it still exists. Therefore, a lane won't continue execution after the main program's termination.</li>
		<li>Just like independant Lua states, Lanes universes cannot communicate together.</li>
	</ul>
</p>


<!-- systems +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="systems">Supported systems</h2>

<p>
	Lua Lanes supports the following operating systems:

	<ul>
		<li>Mac OS X PowerPC / Intel (10.4 and later)</li>
		<li>Linux x86</li>
		<li>Openwrt (15.05 and later)</li>
		<li>Windows 2000/XP and later <font size="-1">(MinGW or Visual C++ 2005/2008)</font></li>
<!--
	Other OS'es here once people help test them. (and the tester's name)

	Win64, BSD, Linux x64, Linux embedded, QNX, Solaris, ...
-->
	</ul>

</p>
<p>
	The underlying threading code can be compiled either towards Win32 API or <a TARGET="_blank" HREF="http://en.wikipedia.org/wiki/POSIX_Threads">Pthreads</a>. Unfortunately, thread prioritization under Pthreads
	requires OS specific tweaks and guessing undocumented behaviour. Other features should be portable to any modern platform.
</p>


<!-- installing +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="installing">Building and Installing</h2>

<p>
	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.
</p>

<p>
	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).
	Or use <A HREF="http://www.luarocks.org" TARGET="_blank">Lua Rocks</A> package management.
</p>

<pre>
	> luarocks search lanes
	... output listing Lua Lanes is there ...

	> luarocks install lanes
	... output ...
</pre>


<!-- embedding +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="embedding">Embedding</h2>
<p>
	When Lanes is embedded, it is possible to statically initialize with
</p>
<table border=1 bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
	<tr>
		<td>
			<pre>	LANES_API void luaopen_lanes_embedded(lua_State* L_, lua_CFunction luaopen_lanes_);</pre>
		</td>
	</tr>
</table>
<p>
	<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.
	<br />
	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>.
</p>

<p>
	To embed Lanes, compile source files in you application. In any Lua state were you want to use Lanes, initialize it as follows:
</p>

<p>
	<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
	<tr>
			<td>
				<pre>	#include "lanes.hpp"</pre>
				<br />
				<pre>	int load_lanes_lua(lua_State* L)</pre>
				<pre>	{</pre>
				<pre>		// retrieve lanes.lua from wherever it is stored and return the result of its execution</pre>
				<pre>		// trivial example 1:</pre>
				<pre>		luaL_dofile(L, "lanes.lua");</pre>
				<br />
				<pre>		// trivial example 2:</pre>
				<pre>		luaL_dostring(L, bin2c_lanes_lua);</pre>
				<pre>	}</pre>
				<br />
				<pre>	void embed_lanes(lua_State* L)</pre>
				<pre>	{</pre>
				<pre>		// we need base libraries for Lanes for work</pre>
				<pre>		luaL_openlibs(L);</pre>
				<pre>		...</pre>
				<pre>		// will attempt luaL_dofile(L, "lanes.lua");</pre>
				<pre>		luaopen_lanes_embedded(L, nullptr);</pre>
				<pre>		lua_pop(L, 1);</pre>
				<pre>		// another example with a custom loader</pre>
				<pre>		luaopen_lanes_embedded(L, load_lanes_lua);</pre>
				<pre>		lua_pop(L, 1);</pre>
				<br />
				<pre>		// a little test to make sure things work as expected</pre>
				<pre>		luaL_dostring(L, "local lanes = require 'lanes'.configure{with_timers = false}; local l = lanes.linda()");</pre>
				<pre>	}</pre>
			</td>
		</tr>
	</table>
</p>

<!-- launching +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>

<h2 id="initialization">Initialization</h2>

<p>
	The following sample shows how to initialize the Lanes module.
</p>

<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
	<tr>
		<td>
			<pre>	local lanes = require "lanes".configure(options|nil)</pre>
		</td>
	</tr>
</table>

<p>
	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 />
	Lanes needs <tt>"base"</tt>, <tt>"string"</tt> and <tt>"table"</tt> to be initialized beforehand (plus <tt>"jit"</tt> for LuaJIT).
</p>
<p>
	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 />
	If <tt>lanes.configure()</tt> is not called before starting to use Lanes, it will be called automatically for you with default settings.<br />
	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 />
	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.
</p>
<p>
	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.
	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.
</p>

<p>
	<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	lanes.configure([opt_tbl])</pre>
			</td>
		</tr>
	</table>
</p>

<p>
	<tt>lanes.configure</tt> accepts an optional options table as sole argument.
	<table border="1" cellpadding="10" style="width:100%">
		<tr>
			<th style="width:15%">name</th>
			<th style="width:15%">value</th>
			<th style="width:70%">definition</th>
		</tr>

		<tr valign=top>
			<td id="allocator">
				<code>.allocator</code>
			</td>
			<td>
				<tt>nil</tt>/<tt>"protected"</tt>/function
			</td>
			<td>
				If <tt>nil</tt>, Lua states are created with <tt>lua_newstate()</tt> and reuse the allocator from the master state.<br />
				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 />
				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:
				<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
					<tr>
						<td>
							<pre>
	static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) {
		lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} };
		// populate _def->allocF and _def->allocUD here
		return 1;
	};
							</pre>
						</td>
					</tr>
				</table>
				The contents will be used to create the state with <tt>lua_newstate(allocF, allocUD)</tt>.
				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.
			</td>
		</tr>

		<tr valign=top>
			<td id="internal_allocator">
				<code>.internal_allocator</code>
			</td>
			<td>
				<tt>"libc"</tt>/<tt>"allocator"</tt>
			</td>
			<td>
				Controls which allocator is used for Lanes internal allocations (for <a href="#keepers">Keeper state</a>, <a href="#lindas">linda</a> and lane management).
				If <tt>"libc"</tt>, Lanes uses <tt>realloc</tt> and <tt>free</tt>.<br />
				If <tt>"allocator"</tt>, Lanes uses whatever was obtained from the <tt>"allocator"</tt> setting.<br />
				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).
			</td>
		</tr>

		<tr valign=top>
			<td id="keepers_gc_threshold">
				<code>.keepers_gc_threshold</code>
			</td>
			<td>integer</td>
			<td>
				If &lt;0, GC runs automatically. This is the default.<br />
				If 0, GC runs after *every* <a href="#keepers">Keeper</a> operation.<br />
				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.
			</td>
		</tr>

		<tr valign=top>
			<td id="nb_user_keepers">
				<code>.nb_user_keepers</code>
			</td>
			<td>integer in [0,100]</td>
			<td>
				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 />
				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 />
				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.
			</td>
		</tr>

		<tr valign=top>
			<td id="on_state_create">
				<code>.on_state_create</code>
			</td>
			<td>
				<tt>nil</tt>/function
			</td>
			<td>
				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 />
				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 />
				If it is a Lua function, it will be transfered normally before the call.<br />
				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 />
				Typical usage is twofold:
				<ul>
					<li>Tweak <tt>package.loaders</tt></li>
					<li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li>
				</ul>
				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 />
			</td>
		</tr>

		<tr valign=top>
			<td id="shutdown_timeout">
				<code>.shutdown_timeout</code>
			</td>
			<td>
				number >= 0
			</td>
			<td>
				Sets the duration in seconds Lanes will wait for graceful termination of running lanes at application shutdown. Default is <tt>0.25</tt>.<br />
				Lanes signals all lanes for cancellation 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 />
				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.
			</td>
		</tr>

		<tr valign=top>
			<td id="strip_functions">
				<code>.strip_functions</code>
			</td>
			<td>
				<tt>nil</tt>/<tt>boolean</tt>
			</td>
			<td>
				Controls function bytecode stripping when dumping them for lane transfer. Choose between faster copies or more debug info. Default is <tt>true</tt>.
			</td>
		</tr>
		<tr valign=top>
			<td id="track_lanes">
				<code>.track_lanes</code>
			</td>
			<td>
				<tt>nil</tt>/<tt>boolean</tt>
			</td>
			<td>
				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.
				Default is <tt>false</tt>.
			</td>
		</tr>

		<tr valign=top>
			<td id="verbose_errors">
				<code>.verbose_errors</code>
			</td>
			<td>
				<tt>nil</tt>/<tt>boolean</tt>
			</td>
			<td>
				If equal to <tt>true</tt>, Lanes will collect more information when transfering stuff across Lua states to help identify errors (with a cost).
				Default is <tt>false</tt>.
			</td>
		</tr>

		<tr valign=top>
			<td id="with_timers">
				<code>.with_timers</code>
			</td>
			<td>
				<tt>nil</tt>/<tt>boolean</tt>
			</td>
			<td>
				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).
				Default is <tt>false</tt>.
			</td>
		</tr>
	</table>
</p>

<p>
	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>.
	<br />
	Use <tt>lanes.require()</tt> for this purpose. This will call the original <tt>require()</tt>, then add the result to the lookup databases.
	<br />
	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 />
	Embedders can call the equivalent function <tt>lanes_register()</tt> from the C side, through <tt>lua_call()</tt> or similar.
</p>

<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
	<tr>
		<td>
			<pre>	local m = lanes.require "modname"</pre>
			<pre>	lanes.register("modname", module)</pre>
		</td>
	</tr>
</table>

<p id="collectgarbage">
	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.
</p>

<p>
	<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	lanes.collectgarbage()</pre>
			</td>
		</tr>
	</table>
</p>

<p id="finally">
	It is also possible to install a function that will be called when Lanes is shutdown (that is, when the first state that required Lanes is closed).
</p>

<p>
	<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	lanes.finally(&lt;some function&gt;|nil)</pre>
			</td>
		</tr>
	</table>
</p>

<p>
	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 />
	Only the last registered finalizer is kept. It can be cleared by passing <tt>nil</tt> or nothing.<br />
	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 />
	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 />
	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 />
	If there are still running lanes when the finalizer returns: Lanes will throw a C++ <tt>std::logic_error</tt> if the finalizer returned <tt>"throw"</tt>. Any other value will cause Lanes to freeze forever.
</p>

<hr/>
<h2 id="creation">Creation</h2>

<p>
	The following sample shows preparing a function for parallel calling, and calling it with varying arguments. Each of the two results is calculated in a separate OS thread, parallel to the calling one. Reading the results joins the threads, waiting for any results not already there.
</p>

<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
	<tr>
		<td>
			<pre>	local lanes = require "lanes"</pre>
			<br />
			<pre>	f = lanes.gen(function(n) return 2 * n end)</pre>
			<pre>	a = f(1)</pre>
			<pre>	b = f(2)</pre>
			<br />
			<pre>	print(a[1], b[1])     -- 2    4</pre>
		</td>
	</tr>
</table>
<br />
<table border=1 bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
	<tr>
		<td>
			<pre>	func = lanes.gen([libs_str | opt_tbl [, ...],] lane_func)</pre>
			<pre>	lane_h = func(...)</pre>
		</td>
	</tr>
</table>

<p>
	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.
	<br />
	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.
</p>

<p>
	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.
</p>

<p>
	<code>libs_str</code> defines the standard libraries made available to the new Lua state:
	<table style="width:100%">
		<tr>
			<td style="width:5%"></td>
			<td>
				<tt>nil</tt>
			</td>
			<td style="width:5%"></td>
			<td>no standard libraries (default)</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"base"</tt>
			</td>
			<td />
			<td>
				<tt>_G</tt> namespace (the default function environment): <tt>print</tt>, <tt>assert</tt>, <tt>dofile</tt>, etc.
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"bit"</tt>
			</td>
			<td />
			<td>
				<tt>bit.*</tt> namespace (LuaJIT)
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"bit32"</tt>
			</td>
			<td />
			<td>
				<tt>bit32.*</tt> namespace (Lua 5.1 and 5.2)
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"coroutine"</tt>
			</td>
			<td />
			<td>
				<tt>coroutine.*</tt> namespace (part of base in Lua 5.1 and 5.2)
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"debug"</tt>
			</td>
			<td />
			<td>
				<tt>debug.*</tt> namespace
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"ffi"</tt>
			</td>
			<td />
			<td>
				<tt>ffi.*</tt> namespace (LuaJIT)
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"io"</tt>
			</td>
			<td />
			<td>
				<tt>io.*</tt> namespace
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"jit"</tt>
			</td>
			<td />
			<td>
				<tt>jit.*</tt> namespace (LuaJIT)
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"math"</tt>
			</td>
			<td />
			<td>
				<tt>math.*</tt> namespace
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"os"</tt>
			</td>
			<td />
			<td>
				<tt>os.*</tt> namespace
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"package"</tt>
			</td>
			<td />
			<td>
				<tt>package.*</tt> namespace and <tt>require</tt>
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"string"</tt>
			</td>
			<td />
			<td>
				<tt>string.*</tt> namespace
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"table"</tt>
			</td>
			<td />
			<td>
				<tt>table.*</tt> namespace
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"utf8"</tt>
			</td>
			<td />
			<td>
				<tt>utf8.*</tt> namespace (Lua 5.3 and above)
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"*"</tt>
			</td>
			<td />
			<td>
				All standard libraries (including those specific to LuaJIT and not listed above), as well as <tt>lanes_core</tt>. This must be used alone.
			</td>
		</tr>
	</table>
</p>

<p>
	Any non-<tt>nil</tt> value causes initialization of <tt>"base"</tt> and <tt>"jit"</tt> (the latter only for LuaJIT-based builds).<br />
	Library names may contain characters matching <tt>std::isalnum(c_) || c_ == '.' || c_ == '-' || c_ == '_'</tt>. Anything else is considered a valid name separator.<br />
	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 />
	Initializing the standard libs takes a bit of time at each lane invocation. This is the main reason why "no libraries" is the default.
</p>

<p>
	<code id="generator_settings">opt_tbl</code> is a collection of named options to control the way lanes are run:
</p>

<p>

	<table border="1" cellpadding="10" style="width:100%">
		<tr>
			<th style="width:15%">name</th>
			<th style="width:15%">value</th>
			<th style="width:70%">definition</th>
		</tr>
		<tr valign=top>
			<td>
				<code>.globals</code>
			</td>
			<td>table</td>
			<td>
				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 />
				The global values of different lanes are in no manner connected; modifying one will only affect the particular lane.
			</td>
		</tr>
		<tr id=".required" valign=top>
			<td>
				<code>.required</code>
			</td>
			<td>table</td>
			<td>
				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>.
				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.
				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.
				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 />
				ATTEMPTING TO TRANSFER A FUNCTION REGISTERED BY A MODULE NOT LISTED HERE WILL RAISE AN ERROR.
			</td>
		</tr>
		<tr id=".error_trace_level" valign=top>
			<td>
				<code>.error_trace_level</code>
			</td>
			<td>string</td>
			<td>
				Sets the error reporting mode. One of <tt>"minimal"</tt> (the default), <tt>"basic"</tt>, <tt>"extended"</tt>.<br />
				<tt>"minimal"</tt> yields only the location of the error.<br />
				The other 2 yield a full stack trace, with different amounts of data extracted from the debug infos. See <a href="#results">Results</a>.
			</td>
		</tr>
		<tr id=".name" valign=top>
			<td>
				<code>.name</code>
			</td>
			<td>string</td>
			<td>
				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).
			</td>
		</tr>
		<tr id=".gc_cb" valign=top>
			<td>
				<code>.gc_cb</code>
			</td>
			<td>function</td>
			<td>
				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>).
			</td>
		</tr>
		<tr valign=top>
			<td>
				<code>.priority</code>
			</td>
			<td>integer</td>
			<td>
				The priority of lanes generated in the range -3..+3 (default is 0).
				These values are a mapping over the actual priority range of the underlying implementation.<br />
				Implementation and dependability of priorities varies by platform. Especially Linux kernel 2.6 is not supporting priorities in user mode.<br />
				A lane can also change its own thread priority dynamically with <a href="#priority"><tt>lanes.set_thread_priority()</tt></a>.
			</td>
		</tr>
		<tr valign=top>
			<td>
				<code>.package</code>
			</td>
			<td> table</td>
			<td>
				Specifying it when <code>libs_str</code> doesn't cause the <code>package</code> library to be loaded will generate an error.<br />
				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.
			</td>
		</tr>
	</table>

<p>
	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 />
	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 />
	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 />
	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 />
	The lane also has a method <tt>lane:get_threadname()</tt> that gives access to that name from the caller side (returns <tt>"&lt;unnamed&gt;"</tt> if unset).<br />
	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>.
</p>

<p>
	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.
	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:

	<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	"type", "name" = lanes.nameof(o)</pre>
			</td>
		</tr>
	</table>
</p>

<h3 id="coroutines">Coroutine lanes</h3>

<p>
	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>.

	<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	local lane_h = lanes.coro(...)(...)</pre>
			</td>
		</tr>
	</table>

	Coroutine lanes function mostly like regular coroutines. They can use <tt>coroutine.yield()</tt> normally, in which case the yielded values can be obtained with regular lane indexing (see <a href="#results">Results and errors</a>).<br />
	A yielded coroutine lane has a <tt>"suspended"</tt> status. It can be resumed with <tt>lane_h:resume(values...)</tt>.
	<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	local yielded_values = lane_h:resume(reply_values...)</pre>
			</td>
		</tr>
	</table>

	The reply values are returned to the lane body at the <tt>coroutine.yield()</tt> point.<br />
	If the yielded values were previously obtained by lane indexing, <tt>resume()</tt> returns <tt>nil</tt>.
</p>
<h3>Free running lanes</h3>

<p>
	The lane handles are allowed to be 'let loose'; in other words you may execute a lane simply by:

	<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	lanes.gen(function(params) ... end ) (...)</pre>
			</td>
		</tr>
	</table>

	Normally, this kind of lanes will be in an eternal loop handling messages. Since the lane handle is gone, there is no way to control such a lane from the outside, nor read its potential return values. Then again, such a lane does not even normally return.
</p>


<!-- priority +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="priority">Priority</h2>

	<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	lanes.set_thread_priority(prio)</pre>
			</td>
		</tr>
	</table>
<p>
	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.
	<br />
	The priority must be in the range <tt>[-3,+3]</tt>.
</p>


<!-- affinity +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="affinity">Affinity</h2>

	<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	lanes.set_thread_affinity(affinity)</pre>
			</td>
		</tr>
	</table>
<p>
	Each thread can change its own affinity at will. This is also true for the main Lua state.
</p>


<!-- status +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="error_trace_level">Error trace level</h2>

	<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	str = lane_h.error_trace_level</pre>
			</td>
		</tr>
	</table>
<p>
	Read back the value set during lane generation, one of <tt>"basic", "minimal", "extended"</tt>.
</p>

<!-- status +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="status">Status</h2>

	<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	str = lane_h.status</pre>
			</td>
		</tr>
	</table>

<p>
	The current execution state of a lane can be read via its <tt>status</tt> member, providing one of these values:

	<table style="width:100%">
		<tr>
			<td style="width:5%"></td>
			<td>
				<tt>"pending"</tt>
			</td>
			<td style="width:5%"></td>
			<td>
				Not started yet. Shouldn't stay very long in that state.
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>
					"running"
				</tt>
			</td>
			<td />
			<td>
				Running, not suspended on a <a href="#lindas">linda</a> call, or yielded on a <tt>coroutine.yield()</tt> call.
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>
					"suspended"
				</tt>
			</td>
			<td />
			<td>
				Coroutine lane stopped at a <tt>coroutine.yield()</tt> point.
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>
					"resuming"
				</tt>
			</td>
			<td />
			<td>
				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.
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"waiting"</tt>
			</td>
			<td />
			<td>
				Waiting at a <a href="#lindas">linda</a> <tt>:receive()</tt> or <tt>:send()</tt>
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"done"</tt>
			</td>
			<td />
			<td>
				Finished executing (results are ready)
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"error"</tt>
			</td>
			<td />
			<td>
				Met an error (reading results will propagate it)
			</td>
		</tr>
		<tr>
			<td />
			<td>
				<tt>"cancelled"</tt>
			</td>
			<td />
			<td>
				Received <a href="#cancelling">cancellation</a> and finished itself.
			</td>
		</tr>
	</table>
</p>

<p>
	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.
</p>


<!-- tracking +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="tracking">Tracking</h2>

	<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%">
		<tr>
			<td>
				<pre>	{name = "name", status = "status", ...}|nil = lanes.threads()</pre>
			</td>
		</tr>
	</table>

<p>
	Only available if lane tracking is enabled by setting <a href="#track_lanes"><tt>track_lanes</tt></a>.
	<br />
	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.
</p>


<!-- results +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="results">Results and errors</h2>

<p>
	Error reporting level is set in the lane generator <a href="#.error_trace_level">settings</a>.
</p>

<p>
	A lane can be waited upon by simply reading its results. This can be done in two ways.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	[val]= lane_h[1]
</pre></td></tr></table>

<p>
	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.
	<br />
	If the lane ended in an error, it is propagated to master state at this place.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	[...]|[nil,err,stack_tbl]= lane_h:join([timeout])
</pre></td></tr></table>

<p>
	Waits until the lane finishes/yields, or <tt>timeout</tt> seconds have passed (forever if <tt>nil</tt>).<br />
	Unlike in reading the results in table fashion, errors are not propagated.<br />
	Possible return values are:
	<ul>
		<li><tt>nil, "timeout"</tt> on timeout.</li>
		<li>
			<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 />
			<ul>
				<li><tt>"minimal"</tt>: <tt>stack_tbl</tt> is <tt>nil</tt>.</li>
				<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>
				<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>
			</ul>
		</li>
		<li><tt>nil, "killed"</tt> if forcefully killed.</li>
		<li>The return values of the lane function. If the first return value is <tt>nil</tt> (or there is no return value), an error is raised, to make sure you can tell timeout and error cases apart from successful return.</li>
	</ul>
	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>. Since it is implicit, the lane body isn't forced to return non-<tt>nil</tt> in that case.
</p>

<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
	local lanes = require "lanes"

	f = lanes.gen(function() error "!!!" end)
	a = f(1)

	--print(a[1])   -- propagates error

	v, err = a:join()   -- no propagation
	if v == nil then
		error("'a' faced error"..tostring(err))   -- manual propagation
	end
</pre></td></tr></table>

<p>
	If you want to wait for multiple lanes to finish (any of a set of lanes), use a <a href="#lindas">linda</a> object. Give each lane a specific id, and send that id over a <a href="#lindas">linda</a> once that thread is done (as the last thing you do).
</p>

<table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
	local lanes = require "lanes"

	local sync_linda = lanes.linda()
	f = lanes.gen(function() dostuff() sync_linda:send("done", true) end)
	a = f()
	b = f()
	c = f()

	sync_linda:receive(nil, sync_linda.batched, "done", 3) -- wait for 3 lanes to write something in "done" slot of sync_linda
</pre></td></tr></table>

<!-- cancelling +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="cancelling">Cancelling</h2>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	bool[,reason] = lane_h:cancel("soft" [, timeout] [, wake_lane])
	bool[,reason] = lane_h:cancel("hard" [, timeout] [, wake_lane])
	bool[,reason] = lane_h:cancel([mode, hookcount] [, timeout] [, wake_lane])
</pre></td></tr></table>

<p>
	<tt>timeout</tt> is an optional number &gt= 0. Defaults to 0 if left unspecified or <tt>nil</tt>.
	<br />
	<tt>cancel()</tt> sends a cancellation request to the lane.
	<br />
	First argument is a <tt>mode</tt> can be one of:
	<ul>
		<li>
			<tt>"soft"</tt>: Cancellation will only cause <tt>cancel_test()</tt> to return <tt>true</tt>, so that the lane can cleanup manually.
		</li>
		<li>
			<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 />
			<tt>wake_lane</tt> defaults to <tt>true</tt>, and <tt>timeout</tt> defaults to 0 if not specified.
		</li>
		<li>
			<tt>"call"</tt>, <tt>"ret"</tt>, <tt>"line"</tt>, <tt>"count"</tt>: Asynchronously install the corresponding hook, then behave as <tt>"hard"</tt>.
		</li>
		<li>
			<tt>"all"</tt>: Installs all hooks in one shot, just to be sure.
		</li>
	</ul>
	If <tt>mode</tt> is not specified, it defaults to <tt>"hard"</tt>.
	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>.
</p>
<p>
	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 />
	Returns <tt>false, "timeout"</tt> otherwise.
</p>
<p>
	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.
</p>
<p>
	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.
	<br />
	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).
	<br />
	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).
	<br />
	It is also possible to manually test for cancel requests with <tt>cancel_test()</tt>.
</p>


<!-- finalizers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="finalizers">Finalizers</h2>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	set_finalizer(finalizer_func)

	void = finalizer_func([err, stack_tbl])
</pre></td></tr></table>

<p>
	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>
	that would get called when a certain block of instructions gets exited, whether through peaceful return or abrupt <tt>error</tt>.
</p>

<p>
	Lanes registers a function <tt>set_finalizer()</tt> in the lane's Lua state for doing this.
	Any functions given to it will be called in the lane Lua state, just prior to closing it. It is possible to set more than one finalizer. They are not called in any particular order.
</p>

<p>
	An error in a finalizer itself overrides the state of the regular chunk (in practice, it would be highly preferable <i>not</i> to have errors in finalizers). If one finalizer errors, the others may not get called.
	If a finalizer error occurs after an error in the lane body, then this new error replaces the previous one (including the full stack trace).
</p>

<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
	local lane_body = function()
		set_finalizer(function(err, stk)
			if err and type(err) ~= "userdata" then
				-- no special error: true error
				print(" error: "..tostring(err))
			elseif type(err) == "userdata" then
				-- lane <a href="#cancelling">cancellation</a> is performed by throwing a special userdata as error
				print("after cancel")
			else
				-- no error: we just got finalized
				print("finalized")
			end
		end)
	end
</pre></td></tr></table>


<!-- lindas +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="lindas">Lindas</h2>

<p>
	Communications between lanes is completely detached from the lane handles themselves. By itself, a lane can only provide return values once it is finished, or throw an error.
	Needs to communicate during runtime are handled by <a href="http://en.wikipedia.org/wiki/Linda_%28coordination_language%29" target="_blank">linda objects</a>, which are
	<a href="#deep_userdata">deep userdata</a> instances. They can be provided to a lane as startup arguments, upvalues or in some other linda's message.
</p>

<p>
	Access to a linda object means a lane can read or write to any of its data slots. Multiple lanes can be accessing the same linda simultaneously. Seen from Lua, no application level locking is required; each linda operation is atomic.
</p>

<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
	local lanes = require "lanes"

	local linda = lanes.linda("my linda")

	local function loop(max)
		for i = 1, max do
			print("sending: " .. i)
			linda:send("x", i)    -- linda as upvalue of loop()
		end
	end

	lane_h = lanes.gen("", loop)(10000)

	while true do
		local slot, val = linda:receive(3.0, "x")    -- timeout in seconds
		if val == nil then
			print("timed out")
			break
		end
		print(tostring(linda) .. " received: " .. val)
	end

	lane_h:join()
</pre></td></tr></table>

<p>
	Characteristics of the Lanes implementation of lindas are:

	<ul>
		<li>Slots can be of boolean, number, string, light userdata, and deep userdata type. Tables, functions and non-deep userdata can't be slots because their identity isn't preserved when transfered from one Lua state to another.</li>
		<li>Values can be any type supported by inter-state copying (same <a href="#limitations">limits</a> as for function arguments and upvalues).</li>
		<li>
			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.
			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.
		</li>
		<li>Consuming method is <tt>:receive</tt> (not in).</li>
		<li>Non-consuming method is <tt>:get</tt> (not rd).</li>
		<li>Two producer-side methods: <tt>:send</tt> and <tt>:set</tt> (not out).</li>
		<li><tt>send</tt> allows for sending multiple values -atomically- to a given slot.</li>
		<li><tt>receive</tt> can wait for multiple slots at once.</li>
		<li><tt>receive</tt> has a batched mode to consume more than one value from a single slot, as in <tt>linda:receive(1.0, linda.batched, "slot", 3, 6).</tt></li>
		<li><tt>restrict</tt> can restrain a particular slot to function either with <tt>send/receive</tt> or <tt>set/get</tt>.</li>
		<li>Individual slots' queue length can be limited, balancing speed differences in a producer/consumer scenario (making <tt>:send</tt> wait).</li>
		<li><tt>tostring(linda)</tt> returns a string of the form <tt>"Linda: &lt;opt_name&gt;"</tt></li>
		<li>
			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>).
			Lanes has an internal linda used for timers and <tt>lanes.wait</tt>; this linda uses group 0.
		</li>
		<li>
			IMPORTANT: *all* linda operations are wrapped inside a <tt>lua_gc STOP/RESTART</tt> pair.
			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>.
		</li>
	</ul>
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	h = lanes.linda([name],[group],[close_handler])
</pre></td></tr></table>

<p>
	Arguments to <tt>lanes.linda()</tt>  can be provided in any order, as long as there is a single string, a single number, and a single callable value (all are optional).<br />
	Converting the linda to a string will yield the provided name prefixed by <tt>"Linda: "</tt>.<br />
	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 />
	If <tt>opt_name</tt> is <tt>"auto"</tt>, Lanes will try to construct a name from the source location that called <tt>lanes.linda()</tt>. If that fails, the linda name will be <tt>"&lt;unresolved&gt;"</tt>.<br />
	If Lanes is configured with more than one Keeper state, <tt>group</tt> is mandatory.<br />
	If the linda is to-be-closed (Lua 5.4+), and a <tt>close_handler</tt> is provided, it will be called with all the provided arguments. For older Lua versions, its presence will cause an error.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	bool,string|(nil,[lanes.cancel_error|"timeout"]) = h:limit(slot, &lt;limit&gt;)
	(number|string),string = h:limit(slot)
</pre></td></tr></table>

<p>
	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 />
	A limit of 0 is allowed to block everything. <tt>"unlimited"</tt> removes the limit.<br />
	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>.
	If no limit is provided, <tt>limit()</tt> first return value is the current limit for the specified slot.<br />
	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>).
	Whether reading or writing, if the linda is cancelled, <tt>limit()</tt> returns <tt>nil, lanes.cancel_error</tt>.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	string|(nil,[lanes.cancel_error|"timeout"]) = h:restrict(slot [, "&lt;mode&gt;"])
	string = h:restrict(slot)
</pre></td></tr></table>

<p>
	It is possible to restrict a particular slot in a Linda to either <tt>send/receive</tt> or <tt>set/get</tt> operations.<br />
	Possible modes are <tt>"none"</tt>, <tt>"set/get"</tt> or <tt>"send/receive"</tt>.<br />
	If a new mode is specified, <tt>restrict()</tt> updates the mode and returns the previous one.<br />
	If no mode is specified, <tt>restrict()</tt> does nothing and returns the current mode.<br />
	If the linda is cancelled, <tt>restrict()</tt> returns <tt>nil, lanes.cancel_error</tt>.<br />
	If an unknown mode is specified, <tt>restrict()</tt> raises an error.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	true|lanes.cancel_error = h:send([timeout_secs,] slot, ...)
</pre></td></tr></table>

<p>
	Timeouts are given in seconds (&gt= 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 />
	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.
</p>

<p>
	Multiple values can be sent to a given slot at once, atomically (the send will fail unless all the values fit within the queue limit). This can be useful for multiple producer scenarios, if the protocols used are giving data in streams of multiple units.
	Atomicity avoids the producers from garbling each others messages, which could happen if the units were sent individually.
</p>

<p>
	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 />
</p>

<p>
	<tt>send()</tt> raises an error if no data is provided after the slot.<br />
	<tt>send()</tt> raises an error if called when a restriction forbids its use on the provided slot.<br />
	<tt>send()</tt> raises <tt>lanes.cancel_error</tt> if interrupted by a hard cancel request.<br />
	<tt>send()</tt> return values can be:
	<ul>
		<li><tt>true</tt> on success.</li>
		<li><tt>nil, "timeout"</tt> if the queue limit was met, and the queue did not empty enough during the given duration.</li>
		<li><tt>nil, lanes.cancel_error</tt> if interrupted by a soft cancel request.</li>
	</ul>
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	slot, val = h:receive([timeout_secs,] slot [, slot...])

	slot, val [, val...] = h:receive([timeout,] h.batched, slot, n_uint_min[, n_uint_max])
</pre></td></tr></table>

<p>
	<tt>receive()</tt> raises an error if called when a restriction forbids its use on any provided slot.<br />
	In batched mode, <tt>receive()</tt> will raise an error if <tt>min_count < 1</tt> or <tt>max_count < min_count</tt>.
</p>

<p>
	Unbatched <tt>receive()</tt> return values can be:
	<ul>
		<li><tt>nil, lanes.cancel_error</tt> if interrupted by a hard cancel request.</li>
		<li><tt>nil, "timeout"</tt> if nothing was available.</li>
		<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>
	</ul>
</p>

<p>
	Note that any number of lanes can be reading or writing a linda. There can be many producers, and many consumers. It is up to you.
</p>

<p>
	Remember that <a href="#cancelling">Hard cancellation</a> will cause pending linda operations to abort execution of the lane through a cancellation error. This means that you have to install a <a href="#finalizers">finalizer</a> in your lane if you want to run some code in that situation.
</p>

<p>
	When receiving from multiple slots, the slots are checked in order, which can be used for making priority queues.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	(bool,string)|(nil,lanes.cancel_error) = linda_h:set(slot [, val [, ...]])

	(number,[val [, ...]])|(nil,lanes.cancel_error) = linda_h:get(slot [, count = 1])
</pre></td></tr></table>

<p>
	<tt>set()</tt> and <tt>get()</tt> raise an error if used when a restriction forbids their use on the provided slot.<br />
	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 />
	<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 />
	<tt>set()</tt> never blocks because it ignores the limit. It overwrites existing values and clears any possible queued entries.<br />
</p>
<p>
	<tt>get()</tt> can read several values at once, and does not block. Return values ares:
	<ul>
		<li><tt>nil, lanes.cancel_error</tt> in case of cancellation.</li>
		<li><tt>number, val...</tt> where number is the actual count of items obtained from the linda (can be 0).</li>
	</ul>
</p>
<p>
	<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 />
	If <tt>set()</tt> actually stores data, the linda is signalled for write, so that <tt>receive()</tt>-blocked Lanes are awakened.<br />
	Clearing the contents of a non-existent slot does not create it!<br />
	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 />
	If the slot was not already full, nothing additional happens, and <tt>set()</tt> first return value is <tt>false</tt>.<br />
	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>).
</p>

<p>
	Trying to send or receive data through a cancelled linda does nothing and returns <tt>lanes.cancel_error</tt>.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	linda_h:collectgarbage()
</pre></td></tr></table>

<p>
	Forces a full garbage collect cycle inside the Keeper state assigned to the Linda (same as <tt>lua_gc(L, LUA_GCCOLLECT)</tt>).<br />
	Can be useful to clean stale storage after some keys are cleaned.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	[val] = linda_h:count([slot[,...]])
</pre></td></tr></table>

<p>
	Returns some information about the contents of the linda.<br />
	If no slot is specified, and the linda is empty, returns nothing.<br />
	If no slot is specified, and the linda is not empty, returns a table of slot/count pairs that counts the number of items in each of the exiting slots of the linda. This count can be 0 if the slot has been used but is empty.<br />
	If a single slot is specified, returns the number of pending items, or nothing if the slot is unknown.<br />
	If more than one slot is specified, return a table of slot/count pairs for the known slots.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	linda_h:dump() ->
	{
		[&lt;slot&gt;] =
		{
			first = &lt;n&gt;
			count = &lt;n&gt;
			limit = &lt;n&gt;|'unlimited'
			restrict = "none"|"set/get"|"send/receive"
			fifo = { &lt;array of values&gt; }
		}
		...
	} 
</pre></td></tr></table>

<p>
	Returns a table describing the full contents of a linda, or <tt>nil</tt> if the linda wasn't used yet.<br />
	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.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	void = linda_h:cancel("read"|"write"|"both"|"none")
	"cancelled"|"active" = linda_h.status
</pre></td></tr></table>

<p>
	<tt>linda:cancel()</tt> signals the linda so that lanes waiting for read, write, or both, wake up.
	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 />
	<tt>"none"</tt> reset the linda's cancel status, but doesn't signal it.<br />
	<tt>linda.status</tt> reads the current cancel status.
	If not void, the lane's cancel status overrides the linda's cancel status.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	void = linda_h:wake("read"|"write"|"both")
</pre></td></tr></table>

<p>
	Signals the linda so that lanes waiting for read, write, or both, wake up. Does not change the current Linda's cancel status. Can be used to break early out of a blocking wait.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	light userdata = h:deep()
</pre></td></tr></table>

<p>
	Returns a light userdata that uniquely represents the linda. The stored value is the same as what is seen when converting an unnamed linda to a string.
</p>

<h3 id="keepers">Granularity of using lindas</h3>

<p>
	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 />
	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 />
	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 />
	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 />
	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 />
	If the thread is woken but the condition is not yet fulfilled, it goes back to sleep, until the timeout expires.<br />
	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 />
</p>

<p>
	A single linda object provides an infinite number of slots, so why would you want to use several?
</p>

<p>
	There are some important reasons:
	<ul>
		<li>
			Access control. If you don't trust certain code completely, or just to modularize your design, use one linda for one usage and another one
			for the other. This keeps your code clear and readable. You can pass multiple linda handles to a lane with practically no added cost.
		</li>

		<li>
			Namespace control. linda slots have a "flat" namespace, so collisions are possible if you try to use the same linda for too many separate uses.
		</li>

		<li>
			Performance. Changing any slot in a linda causes all pending threads for that linda to be momentarily awakened (at least in the C level).
			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.
		</li>
	</ul>

	On the other side, you need to use a common linda for waiting for multiple slots. You cannot wait for slots from two separate linda objects at the same time.
</p>

<p>
	<font size="-1">Actually, you can. Make separate lanes to wait each, and then multiplex those events to a common linda, but... :).</font>
</p>


<!-- timers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="timers">Timers</h2>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	void = lanes.timer(linda_h, slot, date_tbl|first_secs [,period_secs])
</pre></td></tr></table>

<p>
	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.
</p>

<p>
	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.
</p>

<p>
	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 <a href="#lindas">linda</a> <tt>:receive()</tt> method.
</p>

<p>
	A timer can be stopped simply with <tt>first_secs=0|nil</tt> and no period.
</p>

<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
	local lanes = require "lanes"
	lanes.configure{with_timers = true}

	local linda = lanes.linda()

	-- First timer once a second, not synchronized to wall clock
	--
	lanes.timer(linda, "sec", 1, 1)

	-- Timer to a future event (next even minute); wall clock synchronized
	--
	local t = os.date("*t", os.time() + 60)    -- now + 1min
	t.sec = 0

	lanes.timer(linda, "min", t, 60)   -- reoccur every minute (sharp)

	while true do
		local slot, v = linda:receive("sec", "min")
		print("Timer "..slot..": "..v)
	end
</pre></td></tr></table>

<p>
	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.
</p>

<table>
	<tr>
		<td valign=top><i><nobr>Design note:</nobr></i></td>
		<td>
			<font size="-1">
				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.
				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.
				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.
				The current system gives maximum capabilities with minimum API, and any smoothenings can easily be crafted in Lua at the application level.
			</font>
		</td>
	</tr>
</table>

<p></p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	{[{linda, slot, when, period}[,...]]} = lanes.timers()
</pre></td></tr></table>

<p>
	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 />
	Can return <tt>nil, "timeout"</tt> or <tt>nil, lanes.cancel_error</tt> in case of interruption.
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	nil, "timeout" = lanes.sleep(['indefinitely'|seconds|nil])
</pre></td></tr></table>

<p>
	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).
	Default duration is 0, which should only cause a thread context switch.<br />
	Return values should always be <tt>nil, "timeout"</tt> (or <tt>nil, lanes.cancel_error</tt> in case of interruption).
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	number = lanes.now_secs()
</pre></td></tr></table>

<p>
	Returns the current value of the clock used by timers and <a href="#lindas">linda</a> objects.
</p>

<!-- locks +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="locks">Locks etc.</h2>

<p>
	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:
</p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	lock_func|lanes.cancel_error = lanes.genlock(linda_h, slot [,N_uint=1])

	bool|lanes.cancel_error = lock_func(M_uint [, "try"] )     -- acquire
	..
	bool|lanes.cancel_error = lock_func(-M_uint)    -- release
</pre></td></tr></table>

<p>
	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).
	<br />
	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).
	<br />
	Upon successful lock/unlock, <tt>lock_func</tt> returns <tt>true</tt> (always the case when block-waiting for completion).
</p>

<p>
	Note: The generated locks are <u>not recursive</u> (A single lane locking several times will consume tokens at each call, and can therefore deadlock itself). That would need another kind of generator, which is currently not implemented.
</p>

<p>
	Similar sugar exists for atomic counters:
</p>

<p>

<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
	atomic_func|lanes.cancel_error = lanes.genatomic(linda_h, slot [,initial_num=0.0])

	new_num|lanes.cancel_error = atomic_func([diff_num=+1.0])
</pre></td></tr></table>

<p>
	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.
</p>

<p>
	Note that the generated functions can be passed on to other lanes.
</p>


<!-- others +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="other">Other issues</h2>

<h3>Limitations on data passing</h3>

<p>
	Data passed between lanes (either as starting arguments, return values, upvalues or via lindas) must conform to the following:
	<ul>
		<li>Coroutines cannot be passed. A coroutine's Lua state is tied to the Lua state that created it, and there is no way the mixed C/Lua stack of a coroutine can be transfered from one Lua state to another.</li>
		<li>Lane handles cannot be passed between lanes.</li>
		<li>Booleans, numbers, strings, light userdata, Lua functions and tables of such can always be passed.</li>
		<li>
			Cyclic tables and/or duplicate references are allowed and reproduced appropriately, but only <u>within the same transmission</u>.
			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).
		</li>
		<li>
			For tables and full userdata: before anything else, the metatable is searched for a <tt>__lanesconvert</tt> field. If found, the source object is converted as follows depending on <tt>__lanesconvert</tt>'s value:
			<ul>
				<li><tt>lanes.null</tt>: The value is converted to <tt>nil</tt>.</li>
				<li><tt>"decay"</tt>: The value is converted to a light userdata obtained from <tt>lua_topointer()</tt>.</li>
				<li>A function: The function is called as <tt>o:__lanesconvert(string)</tt>, where the argument is either <tt>"keeper"</tt> or <tt>"regular"</tt>, depending on the type of destination. Its (single) return value is the result of the conversion.</li>
				<li>Any other value raises an error.</li>
			</ul>
		</li>
		<li>
			Non-converted full userdata can be passed only if it registered, or prepared using the <a href="#deep_userdata">deep userdata</a> system, which handles its lifespan management.
		</li>
		<li>
			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.
		</li>
		<li>
			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.
		</li>
		<li>
			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>.
			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
			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.
		</li>
	</ul>
</p>


<h3 id="function_notes">Notes about passing C functions and full userdata</h3>

<p>
	C functions and full userdata are transfered as follows (more or less):
</p>

<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
	// expects a C function or full userdata on top of the source Lua stack
	copyValue(lua_State *dest, lua_State* source)
	{
		// fetch function 'name' from source lookup database
		char const* valuename = lookup_name(source, -1);
		// lookup a function or userdata bound to this name in the destination state, and push it on the stack
		push_resolved_value(dest, valuename);
	}
</pre></td></tr></table>

<p>
	The devil lies in the details: what does "lookup" mean?
</p>

<p>
	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.
	<br />
	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.
	<br />
	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.
	<br />
	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.
	<br />
	Each time a function or full userdata is encountered, the sequence of keys traversed to reach it is contatenated in a (hopefully) unique name. The [name, value] and [value, name] pairs are both stored in a lookup table in all involved Lua states (main Lua state and lanes states).
	<br />
	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.
	<br />
	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).
</p>

<p>
	There are several issues here:
	<ul>
		<li>
			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 />
			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>.
		</li>
		<li>
			Nothing prevents a script to create other references to a C function or full userdata. For example one could do
			<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
				string2 = string
			</pre></td></tr></table>
			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.
			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.
			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>
			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>).
		</li>
		<li>
			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.
			When Lua is built with compatibility options (such as LUA_COMPAT_ALL), this causes several base libraries to register functions under multiple names.
			This, with the randomizer, can cause the first encountered name of a function to be different on different VMs, which breaks function transfer.
			Even under Lua 5.1, this may cause trouble if some module registers a function under several keys.
			To circumvent this, Lanes has to select one name among all candidates, and the rule for this is to keep the 'smaller' one: first in byte count, then in lexical order.
		</li>
	</ul>
	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.
	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.
	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.
</p>


<h3>Required of module makers</h3>

<p>
	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.
</p>

<p>
	If it, however, also does one-time C side initializations, these should be covered into a one-time-only construct such as below.
</p>

<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
	int luaopen_module(lua_State *L )
	{
		static char been_here;  /* 0 by ANSI C */

		// Calls to 'require' serialized by Lanes; this is safe.
		if (!been_here)
		{
			been_here= 1;
			... one time initializations ...
		}
		... binding to Lua ...
	}
</pre></td></tr></table>

<h3 id="clonable_userdata">Clonable full userdata in your own apps</h3>
<p>
	An alternative way of passing full userdata across lanes uses a new <tt>__lanesclone</tt> metamethod.
	When a deep userdata is cloned, Lanes calls <tt>__lanesclone</tt> once, in the context of the source lane.<br />
	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 />
	A typical implementation would look like:
<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
static int clonable_lanesclone(lua_State* L)
{
	switch(lua_gettop(L))
	{
		case 3:
		{
			struct s_MyClonableUserdata* self = lua_touserdata(L, 1);
			struct s_MyClonableUserdata* from = lua_touserdata(L, 2);
			size_t len = lua_tointeger(L, 3);
			assert(len == sizeof(struct s_MyClonableUserdata));
			*self = *from;
		}
		return 0;

		default:
		std::ignore = luaL_error(L, "Lanes called clonable_lanesclone with unexpected arguments");
	}
	return 0;
}
</pre></td></tr></table>
</p>

<p>
	<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 />
	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:
<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
int luaopen_deep_userdata_example(lua_State* L)
{
	luaL_newlib(L, deep_module);

	// preregister the metatables for the types we can instanciate so that Lanes can know about them
	if (luaL_newmetatable(L, "clonable"))
	{
		luaL_setfuncs(L, clonable_mt, 0);
		lua_pushvalue(L, -1);
		lua_setfield(L, -2, "__index");
	}
	lua_setfield(L, -2, "__clonableMT"); // actual name is not important

	if (luaL_newmetatable(L, "deep"))
	{
		luaL_setfuncs(L, deep_mt, 0);
		lua_pushvalue(L, -1);
		lua_setfield(L, -2, "__index");
	}
	lua_setfield(L, -2, "__deepMT"); // actual name is not important

	return 1;
}
</pre></td></tr></table>
</p>

<p>
	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.
<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
int luaD_new_clonable(lua_State* L)
{
	lua_newuserdata(L, sizeof(struct s_MyClonableUserdata));
	luaL_setmetatable(L, "clonable");
	return 1;
}
</pre></td></tr></table>
</p>

<h3 id="deep_userdata">Deep userdata in your own apps</h3>

<p>
	The mechanism Lanes uses for sharing <a href="#lindas">linda</a> handles between separate Lua states can be used for custom userdata as well. Here's what to do.
</p>

<ol>
	<li>
		Provide a <i>factory</i> for your userdata. This object is used for creation and deletion of your deep userdata (the shared resource), and for making metatables for the state-specific proxies for accessing it. The prototype is
<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
class MyDeepFactory : public DeepFactory
{
	private:

	void createMetatable(lua_State* const L_) const override;
	void deleteDeepObjectInternal(lua_State* const L_, DeepPrelude* o_) const override;
	DeepPrelude* newDeepObjectInternal(lua_State* const L_) const override;
	std::string_view moduleName() const override;
};

static MyDeepFactory g_MyDeepFactory;
</pre></td></tr></table>
		<ul>
			<li><tt>newDeepObjectInternal()</tt>: requests the creation of a new object, whose pointer is returned. Said object must derive from <tt>DeepPrelude</tt>.</li>
			<li><tt>deleteDeepObjectInternal()</tt>: should cleanup the object.</li>
			<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>
			<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>
		</ul>
		Take a look at <tt>LindaFactory</tt> in <tt>lindafactory.cpp</tt> or <tt>MyDeepFactory</tt> in <tt>deep_userdata_example.cpp</tt>.
	</li>
	<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.
	<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>
	<li>Accessing the deep userdata from your C code, use <tt>yourFactoryObject.toDeep()</tt> instead of the regular <tt>lua_touserdata()</tt>.</li>
	<li>To push an existing proxy on the stack, use <tt>DeepPrelude::push(L)</tt>.</li>
</ol>

<p>
	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.
</p>

<p>
	Pay attention to the fact a deep userdata last proxy can be held inside a Keeper state after being stored in a Linda and all other references are lost.
	If the Linda then flushes its contents through garbage collection in the Keeper state or by being collected itself, it means that <tt>deleteDeepObjectInternal()</tt> can be called from inside a Keeper state.
</p>

<p>
	<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.
</p>


<h3>Lane handles don't travel</h3>

<p>
	Lane handles are not implemented as deep userdata, and cannot thus be copied across lanes. This is intentional; problems would occur at least when multiple lanes were to wait upon one to get ready. Also, it is a matter of design simplicity.
</p>

<p>
	The same benefits can be achieved by having a single worker lane spawn all the sublanes, and keep track of them. Communications to and from this lane can be handled via a <a href="#lindas">linda</a>.
</p>


<h3>Beware with print and file output</h3>

<p>
	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:

<table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre>
	A:  print(1, 2, 3, 4 )
	B:  print('a', 'b', 'c', 'd' )

	1   a   b   2   3   c   d   4
</pre></td></tr></table>

	Lanes does not protect you from this behaviour. The thing to do is either to concentrate your output to a certain lane per stream, or to concatenate output into a single string before you call the output function.
</p>


<h3 id="performance">Performance considerations</h3>

<p>
	Lanes is about making multithreading easy, and natural in the Lua state of mind. Expect performance not to be an issue, if your program is logically built. Here are some things one should consider, if best performance is vital:
</p>

<p>
	<ul>
		<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>
		<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>
		<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>
		<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>
		<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>
		<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>
</ul>
</p>


<h3 id="cancelling_cancel">Cancelling cancel</h3>

<p>
	Cancellation of lanes uses the Lua error mechanism with a special lightuserdata error sentinel.
	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.
	You should throw any lightuserdata error further.
</p>

<p>
	This system can actually be used by application to detect cancel, do your own cancellation duties, and pass on the error so Lanes will get it. If it does not get a clean cancellation from a lane in due time, it may forcefully kill the lane.
</p>

<p>
	The sentinel is exposed as <tt>lanes.cancel_error</tt>, if you wish to use its actual value.
</p>



<!-- change log +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>
<h2 id="changes">Change log</h2>

<p>
	See CHANGES.
</p>

<!-- footnotes +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<hr/>

<p>
	For feedback, questions and suggestions:
	<ul>
		<li><A HREF="http://github.com/LuaLanes/lanes">Lanes @ GitHub</A></li>
		<li><A HREF="mailto:bnt.germain@gmail.com">the maintainer</A></li>
		<li><A HREF="http://www.lua.org/lua-l.html">the lua mailing list</A></li>
	</ul>
</p>

</body>
</html>