diff options
Diffstat (limited to 'docs/index.html')
-rw-r--r-- | docs/index.html | 205 |
1 files changed, 162 insertions, 43 deletions
diff --git a/docs/index.html b/docs/index.html index d0f3940..2e74495 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -38,6 +38,7 @@ | |||
38 | <a href="#description">Description</a> · | 38 | <a href="#description">Description</a> · |
39 | <a href="#systems">Supported systems</a> · | 39 | <a href="#systems">Supported systems</a> · |
40 | <a href="#installing">Building and Installing</a> · | 40 | <a href="#installing">Building and Installing</a> · |
41 | <a href="#apicheatsheet">API Cheat sheet</a> | ||
41 | <a href="#embedding">Embedding</a> | 42 | <a href="#embedding">Embedding</a> |
42 | </p> | 43 | </p> |
43 | 44 | ||
@@ -64,13 +65,13 @@ | |||
64 | <font size="-1"> | 65 | <font size="-1"> |
65 | <p> | 66 | <p> |
66 | <br /> | 67 | <br /> |
67 | <i>Copyright © 2007-24 Asko Kauppi, Benoit Germain. All rights reserved.</i> | 68 | <i>Copyright © 2007-25 Asko Kauppi, Benoit Germain. All rights reserved.</i> |
68 | <br /> | 69 | <br /> |
69 | Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1, 5.2, 5.3 and 5.4. | 70 | Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1, 5.2, 5.3, 5.4 and 5.5. |
70 | </p> | 71 | </p> |
71 | 72 | ||
72 | <p> | 73 | <p> |
73 | This document was revised on 17-Mar-25, and applies to version <tt>4.0.0</tt>. | 74 | This document was revised on 03-Jul-25, and applies to version <tt>4.0.0</tt>. |
74 | </p> | 75 | </p> |
75 | </font> | 76 | </font> |
76 | </center> | 77 | </center> |
@@ -88,7 +89,7 @@ | |||
88 | 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. | 89 | Lanes is included into your software by the regular <tt>require "lanes"</tt> method. No C side programming is needed; all APIs are Lua side, and most existing extension modules should work seamlessly together with the multiple lanes. |
89 | </p> | 90 | </p> |
90 | <p> | 91 | <p> |
91 | Lanes should build and run identically with either Lua 5.1 to Lua 5.4, as well as LuaJIT. | 92 | Lanes should build and run identically with either Lua 5.1 to Lua 5.5, as well as LuaJIT. |
92 | </p> | 93 | </p> |
93 | <p> | 94 | <p> |
94 | See <A HREF="comparison.html">comparison</A> of Lua Lanes with other Lua multithreading solutions. | 95 | See <A HREF="comparison.html">comparison</A> of Lua Lanes with other Lua multithreading solutions. |
@@ -105,7 +106,7 @@ | |||
105 | <li>Threads can be given priorities.</li> | 106 | <li>Threads can be given priorities.</li> |
106 | <li>Lanes are cancellable, with proper cleanup.</li> | 107 | <li>Lanes are cancellable, with proper cleanup.</li> |
107 | <li>No Lua-side application level locking - ever!</li> | 108 | <li>No Lua-side application level locking - ever!</li> |
108 | <li>Several totally independant Lanes universes may coexist in an application, one per "master" Lua state.</li> | 109 | <li>Several totally independent Lanes universes may coexist in an application, one per "master" Lua state.</li> |
109 | </ul> | 110 | </ul> |
110 | 111 | ||
111 | 112 | ||
@@ -116,7 +117,7 @@ | |||
116 | <li>Sharing full userdata between states needs special C side preparations (-> <A HREF="#deep_userdata">deep userdata</A> and -> <A HREF="#clonable_userdata">clonable userdata</A>).</li> | 117 | <li>Sharing full userdata between states needs special C side preparations (-> <A HREF="#deep_userdata">deep userdata</A> and -> <A HREF="#clonable_userdata">clonable userdata</A>).</li> |
117 | <li>Network level parallelism not included.</li> | 118 | <li>Network level parallelism not included.</li> |
118 | <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> | 119 | <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> |
119 | <li>Just like independant Lua states, Lanes universes cannot communicate together.</li> | 120 | <li>Just like independent Lua states, Lanes universes cannot communicate together.</li> |
120 | </ul> | 121 | </ul> |
121 | </p> | 122 | </p> |
122 | 123 | ||
@@ -169,6 +170,84 @@ | |||
169 | </pre> | 170 | </pre> |
170 | 171 | ||
171 | 172 | ||
173 | <!-- API reference +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
174 | <hr/> | ||
175 | <h2 id="apicheatsheet">API Cheat sheet</h2> | ||
176 | <ul> | ||
177 | <li> | ||
178 | <tt>require "lanes"</tt>: to require Lanes | ||
179 | </li> | ||
180 | <li> | ||
181 | The <tt>lanes</tt> module | ||
182 | <ul> | ||
183 | <li><tt>lanes.cancel_error</tt>: a special error value returned from cancelled lanes</li> | ||
184 | <li><tt>lanes.collectgarbage()</tt>: trigger a GC cycle in all Keeper states</li> | ||
185 | <li><tt>lanes.configure()</tt>: configure Lanes</li> | ||
186 | <li><tt>lanes.coro()</tt>: start a coroutine-like lane</li> | ||
187 | <li><tt>lanes.finally()</tt>: install a function called on Lanes shutdown</li> | ||
188 | <li><tt>lanes.gen()</tt>: start a lane as a regular function</li> | ||
189 | <li><tt>lanes.genactomic()</tt>: obtain an atomic counter</li> | ||
190 | <li><tt>lanes.genlock()</tt>: obtain an atomic-like data stack</li> | ||
191 | <li><tt>lanes.linda()</tt>: create a Linda</li> | ||
192 | <li><tt>lanes.nameof()</tt>: find where a value exists</li> | ||
193 | <li><tt>lanes.thread_priority_range()</tt>: obtain the valid range of thread priorities</li> | ||
194 | <li><tt>lanes.now_secs()</tt>: obtain the current clock value</li> | ||
195 | <li><tt>lanes.register()</tt>: scan modules so that functions using them can be transferred</li> | ||
196 | <li><tt>lanes.set_thread_priority()</tt>: change thread priority</li> | ||
197 | <li><tt>lanes.set_thread_affinity()</tt>: change thread affinity</li> | ||
198 | <li><tt>lanes.threads()</tt>: obtain a list of all lanes</li> | ||
199 | <li><tt>lanes.sleep()</tt>: sleep for a given duration</li> | ||
200 | <li><tt>lanes.timer()</tt>: start a timer</li> | ||
201 | <li><tt>lanes.timers()</tt>: list active timers</li> | ||
202 | </ul> | ||
203 | </li> | ||
204 | <li> | ||
205 | Given some lane handle <tt>lane_h</tt> | ||
206 | <ul> | ||
207 | <li><tt>lane_h[]</tt>: wait for, and read the values returned by the lane</li> | ||
208 | <li><tt>lane_h:cancel()</tt>: request the lane to stop running</li> | ||
209 | <li><tt>lane_h.error_trace_level</tt>: current setting of error logging level</li> | ||
210 | <li><tt>lane_h:get_threadname()</tt>: read the thread name</li> | ||
211 | <li><tt>lane_h:join()</tt>: wait for the lane to close, reading the returned values</li> | ||
212 | <li><tt>lane_h:resume()</tt>: resume a coroutine Lane</li> | ||
213 | <li><tt>lane_h.status</tt>: current status of the lane</li> | ||
214 | </ul> | ||
215 | </li> | ||
216 | <li> | ||
217 | Inside the lane | ||
218 | <ul> | ||
219 | <li><tt>cancel_test()</tt>: check for cancellation requests</li> | ||
220 | <li><tt>lane_threadname()</tt>: read or change the name of the thread</li> | ||
221 | <li><tt>set_finalizer()</tt>: install a function called when the lane exits</li> | ||
222 | </ul> | ||
223 | </li> | ||
224 | <li> | ||
225 | Given some Linda <tt>l</tt> | ||
226 | <ul> | ||
227 | <li><tt>l:cancel()</tt>: mark a Linda for cancellation</li> | ||
228 | <li><tt>l:collectgarbage()</tt>: trigger a GC cycle in the Linda's Keeper state</li> | ||
229 | <li><tt>l:deep()</tt>: obtain a light userdata uniquely representing the Linda</li> | ||
230 | <li><tt>l:dump()</tt>: have information about slot contents</li> | ||
231 | <li><tt>l:count()</tt>: obtain a count of data items in slots</li> | ||
232 | <li><tt>l:get()</tt>: read data without consuming it</li> | ||
233 | <li><tt>l:limit()</tt>: cap the amount of transiting data</li> | ||
234 | <li><tt>l:receive()</tt>: read one item of data from multiple slots</li> | ||
235 | <li><tt>l:receive_batched()</tt>: read several item of data from a single slot</li> | ||
236 | <li><tt>l:restrict()</tt>: place a restraint on the operations that can be done on a slot</li> | ||
237 | <li><tt>l:send()</tt>: append data</li> | ||
238 | <li><tt>l:set()</tt>: replace the data</li> | ||
239 | <li><tt>l:wake()</tt>: manually wake blocking calls</li> | ||
240 | </ul> | ||
241 | </li> | ||
242 | <li> | ||
243 | embedding | ||
244 | <ul> | ||
245 | <li><tt>luaopen_lanes_embedded</tt>: manually initialize Lanes</li> | ||
246 | </ul> | ||
247 | </li> | ||
248 | </ul> | ||
249 | |||
250 | |||
172 | <!-- embedding +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 251 | <!-- embedding +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
173 | <hr/> | 252 | <hr/> |
174 | <h2 id="embedding">Embedding</h2> | 253 | <h2 id="embedding">Embedding</h2> |
@@ -271,7 +350,7 @@ | |||
271 | </p> | 350 | </p> |
272 | 351 | ||
273 | <p> | 352 | <p> |
274 | <tt>lanes.configure</tt> accepts an optional options table as sole argument. | 353 | <tt>lanes.configure</tt> accepts an optional table as sole argument. |
275 | <table border="1" cellpadding="10" style="width:100%"> | 354 | <table border="1" cellpadding="10" style="width:100%"> |
276 | <tr> | 355 | <tr> |
277 | <th style="width:15%">name</th> | 356 | <th style="width:15%">name</th> |
@@ -337,6 +416,22 @@ | |||
337 | </tr> | 416 | </tr> |
338 | 417 | ||
339 | <tr valign=top> | 418 | <tr valign=top> |
419 | <td id="linda_wake_period"> | ||
420 | <code>.linda_wake_period</code> | ||
421 | </td> | ||
422 | <td> | ||
423 | number > 0 | ||
424 | </td> | ||
425 | <td> | ||
426 | Sets the default period in seconds a linda will wake by itself during blocked operations. Default is never.<br /> | ||
427 | When a Linda enters a blocking call (<tt>send()</tt>, <tt>receive()</tt>, <tt>receive_batched()</tt>, <tt>sleep()</tt>), it normally sleeps either until the operation completes | ||
428 | or the specified timeout expires. With this setting, the default behavior can be changed to wake periodically. This can help for example with timing issues where a lane is signalled | ||
429 | for cancellation, but a linda inside the lane was in the middle of processing an operation but did not actually start the wait. This can result in the signal to be ignored, thus | ||
430 | causing the Linda to wait out the full operation timeout before cancellation is processed. | ||
431 | </td> | ||
432 | </tr> | ||
433 | |||
434 | <tr valign=top> | ||
340 | <td id="nb_user_keepers"> | 435 | <td id="nb_user_keepers"> |
341 | <code>.nb_user_keepers</code> | 436 | <code>.nb_user_keepers</code> |
342 | </td> | 437 | </td> |
@@ -769,12 +864,13 @@ | |||
769 | </tr> | 864 | </tr> |
770 | <tr valign=top> | 865 | <tr valign=top> |
771 | <td> | 866 | <td> |
772 | <code>.priority</code> | 867 | <code>.priority</code><br /> |
868 | <code>.native_priority</code> | ||
773 | </td> | 869 | </td> |
774 | <td>integer</td> | 870 | <td>integer</td> |
775 | <td> | 871 | <td> |
776 | The priority of lanes generated in the range -3..+3 (default is 0). | 872 | <tt>priority</tt>: The priority of lanes in the range <tt>[-3,+3]</tt> (default is 0). These values are a mapping over the actual priority range of the underlying implementation.<br /> |
777 | These values are a mapping over the actual priority range of the underlying implementation.<br /> | 873 | <tt>native_priority</tt>: The priority of lanes in a platform-dependent range. Use <a href="#priority"><tt>lanes.thread_priority_range()</tt></a> to query said range. |
778 | Implementation and dependability of priorities varies by platform. Especially Linux kernel 2.6 is not supporting priorities in user mode.<br /> | 874 | Implementation and dependability of priorities varies by platform. Especially Linux kernel 2.6 is not supporting priorities in user mode.<br /> |
779 | A lane can also change its own thread priority dynamically with <a href="#priority"><tt>lanes.set_thread_priority()</tt></a>. | 875 | A lane can also change its own thread priority dynamically with <a href="#priority"><tt>lanes.set_thread_priority()</tt></a>. |
780 | </td> | 876 | </td> |
@@ -797,7 +893,7 @@ | |||
797 | 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 /> | 893 | 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 /> |
798 | 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 /> | 894 | 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 /> |
799 | The lane also has a method <tt>lane:get_threadname()</tt> that gives access to that name from the caller side (returns <tt>"<unnamed>"</tt> if unset).<br /> | 895 | The lane also has a method <tt>lane:get_threadname()</tt> that gives access to that name from the caller side (returns <tt>"<unnamed>"</tt> if unset).<br /> |
800 | 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>. | 896 | 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>. |
801 | </p> | 897 | </p> |
802 | 898 | ||
803 | <p> | 899 | <p> |
@@ -826,8 +922,9 @@ | |||
826 | </tr> | 922 | </tr> |
827 | </table> | 923 | </table> |
828 | 924 | ||
829 | 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 /> | 925 | Coroutine lanes function mostly like regular coroutines. They can use <tt>coroutine.yield()</tt> normally.<br /> |
830 | A yielded coroutine lane has a <tt>"suspended"</tt> status. It can be resumed with <tt>lane_h:resume(values...)</tt>. | 926 | A yielded coroutine lane has a <tt>"suspended"</tt> status. It can be resumed with <tt>lane_h:resume(values...), which returns the yielded values</tt>. |
927 | The latter can also be the returned values of <tt>lane_h:join()</tt> or accessed by regular lane indexing (see <a href="#results">Results and errors</a>).<br /> | ||
831 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> | 928 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"> |
832 | <tr> | 929 | <tr> |
833 | <td> | 930 | <td> |
@@ -836,8 +933,8 @@ | |||
836 | </tr> | 933 | </tr> |
837 | </table> | 934 | </table> |
838 | 935 | ||
839 | The reply values are returned to the lane body at the <tt>coroutine.yield()</tt> point.<br /> | 936 | Just like regulare coroutines, the reply values passed to <tt>h:resume()</tt> are returned to the lane body at the <tt>coroutine.yield()</tt> point.<br /> |
840 | If the yielded values were previously obtained by lane indexing, <tt>resume()</tt> returns <tt>nil</tt>. | 937 | If a coroutine lane is suspended when it is joined either by indexing or <tt>lane_h:join()</tt>, active to-be-closed variables are closed at that point, and the Lane can no longer be resumed. |
841 | </p> | 938 | </p> |
842 | <h3>Free running lanes</h3> | 939 | <h3>Free running lanes</h3> |
843 | 940 | ||
@@ -863,14 +960,17 @@ | |||
863 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> | 960 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> |
864 | <tr> | 961 | <tr> |
865 | <td> | 962 | <td> |
866 | <pre> lanes.set_thread_priority(prio)</pre> | 963 | <pre> prio_min, prio_max = lanes.thread_priority_range(prio [,"native"])</pre> |
964 | <pre> lanes.set_thread_priority(prio [,"native"])</pre> | ||
867 | </td> | 965 | </td> |
868 | </tr> | 966 | </tr> |
869 | </table> | 967 | </table> |
870 | <p> | 968 | <p> |
871 | 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. | 969 | 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. |
872 | <br /> | 970 | <br /> |
873 | The priority must be in the range <tt>[-3,+3]</tt>. | 971 | <tt>lanes.thread_priority_range()</tt> returns the range of acceptable mapped values. If nothing is specified, should be <tt>[-3,3]</tt> or <tt>[0,3]</tt>, depending on the threading implementation. |
972 | <br /> | ||
973 | <tt>lanes.thread_priority_range('native')</tt> returns the range of acceptable native values. The actual values are threading implementation dependent. And some implementations can only accept some values inside that range. YMMV. | ||
874 | </p> | 974 | </p> |
875 | 975 | ||
876 | 976 | ||
@@ -1057,7 +1157,7 @@ | |||
1057 | </p> | 1157 | </p> |
1058 | 1158 | ||
1059 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1159 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1060 | [...]|[nil,err,stack_tbl]= lane_h:join([timeout]) | 1160 | [true, ...]|[nil,err,stack_tbl]= lane_h:join([timeout]) |
1061 | </pre></td></tr></table> | 1161 | </pre></td></tr></table> |
1062 | 1162 | ||
1063 | <p> | 1163 | <p> |
@@ -1075,9 +1175,9 @@ | |||
1075 | </ul> | 1175 | </ul> |
1076 | </li> | 1176 | </li> |
1077 | <li><tt>nil, "killed"</tt> if forcefully killed.</li> | 1177 | <li><tt>nil, "killed"</tt> if forcefully killed.</li> |
1078 | <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> | 1178 | <li><tt>true [, returned-values]</tt>: The return values of the lane function.</li> |
1079 | </ul> | 1179 | </ul> |
1080 | 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. | 1180 | 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>. |
1081 | </p> | 1181 | </p> |
1082 | 1182 | ||
1083 | <table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> | 1183 | <table border=1 bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> |
@@ -1107,7 +1207,7 @@ | |||
1107 | b = f() | 1207 | b = f() |
1108 | c = f() | 1208 | c = f() |
1109 | 1209 | ||
1110 | sync_linda:receive(nil, sync_linda.batched, "done", 3) -- wait for 3 lanes to write something in "done" slot of sync_linda | 1210 | sync_linda:receive_batched(nil, "done", 3) -- wait for 3 lanes to write something in "done" slot of sync_linda |
1111 | </pre></td></tr></table> | 1211 | </pre></td></tr></table> |
1112 | 1212 | ||
1113 | <!-- cancelling +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 1213 | <!-- cancelling +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
@@ -1121,38 +1221,49 @@ | |||
1121 | </pre></td></tr></table> | 1221 | </pre></td></tr></table> |
1122 | 1222 | ||
1123 | <p> | 1223 | <p> |
1124 | <tt>timeout</tt> is an optional number >= 0. Defaults to 0 if left unspecified or <tt>nil</tt>. | ||
1125 | <br /> | ||
1126 | <tt>cancel()</tt> sends a cancellation request to the lane. | 1224 | <tt>cancel()</tt> sends a cancellation request to the lane. |
1127 | <br /> | 1225 | <p> |
1128 | First argument is a <tt>mode</tt> can be one of: | 1226 | 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 /> |
1227 | Returns <tt>false, "timeout"</tt> otherwise. | ||
1228 | </p> | ||
1229 | First argument is a <tt>mode</tt>. It can be one of: | ||
1129 | <ul> | 1230 | <ul> |
1130 | <li> | 1231 | <li> |
1131 | <tt>"soft"</tt>: Cancellation will only cause <tt>cancel_test()</tt> to return <tt>true</tt>, so that the lane can cleanup manually. | 1232 | <tt>"soft"</tt>: Cancellation will only cause <tt>cancel_test()</tt> to return <tt>"soft"</tt>, so that the lane can cleanup manually. |
1233 | <br /> | ||
1234 | Lindas will also check for cancellation inside blocking calls to early out based on their <tt>wake_period</tt>. | ||
1132 | </li> | 1235 | </li> |
1133 | <li> | 1236 | <li> |
1134 | <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 /> | 1237 | <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). |
1238 | <br /> | ||
1239 | If the lane isn't actually waiting on a Linda when the request is issued, a lane calling <tt>cancel_test()</tt> will see it return <tt>"hard"</tt>. | ||
1240 | <br /> | ||
1135 | <tt>wake_lane</tt> defaults to <tt>true</tt>, and <tt>timeout</tt> defaults to 0 if not specified. | 1241 | <tt>wake_lane</tt> defaults to <tt>true</tt>, and <tt>timeout</tt> defaults to 0 if not specified. |
1136 | </li> | 1242 | </li> |
1137 | <li> | 1243 | <li> |
1138 | <tt>"call"</tt>, <tt>"ret"</tt>, <tt>"line"</tt>, <tt>"count"</tt>: Asynchronously install the corresponding hook, then behave as <tt>"hard"</tt>. | 1244 | <tt>"call"</tt>, <tt>"ret"</tt>, <tt>"line"</tt>, <tt>"count"</tt>: Asynchronously install the corresponding hook, then behave as <tt>"hard"</tt>. |
1245 | <br /> | ||
1246 | If the lane has the opportunity to call <tt>cancel_test()</tt> before the hook is invoked, calling <tt>cancel_test()</tt> will see it return <tt>"hard"</tt>. | ||
1139 | </li> | 1247 | </li> |
1140 | <li> | 1248 | <li> |
1141 | <tt>"all"</tt>: Installs all hooks in one shot, just to be sure. | 1249 | <tt>"all"</tt>: Installs all hooks in one shot, just to be sure. |
1142 | </li> | 1250 | </li> |
1143 | </ul> | 1251 | </ul> |
1144 | If <tt>mode</tt> is not specified, it defaults to <tt>"hard"</tt>. | 1252 | <p> |
1253 | If <tt>mode</tt> is not specified, it defaults to <tt>"hard"</tt>. | ||
1254 | </p> | ||
1255 | </p> | ||
1256 | <p> | ||
1145 | 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>. | 1257 | 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>. |
1146 | </p> | 1258 | </p> |
1147 | <p> | 1259 | <p> |
1148 | 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 /> | 1260 | <tt>timeout</tt> is an optional number >= 0. Defaults to infinite if left unspecified or <tt>nil</tt>. |
1149 | Returns <tt>false, "timeout"</tt> otherwise. | ||
1150 | </p> | 1261 | </p> |
1151 | <p> | 1262 | <p> |
1152 | 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. | 1263 | 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. |
1153 | </p> | 1264 | </p> |
1154 | <p> | 1265 | <p> |
1155 | 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. | 1266 | Cancellation is tested <u>before</u> going to sleep in <tt>receive()</tt>, <tt>receive_batched()</tt> or <tt>send()</tt> calls and after executing <tt>cancelstep</tt> Lua statements. A pending <tt>receive()</tt>or <tt>send()</tt> call is awakened. |
1156 | <br /> | 1267 | <br /> |
1157 | 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). | 1268 | 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). |
1158 | <br /> | 1269 | <br /> |
@@ -1222,7 +1333,7 @@ | |||
1222 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> | 1333 | <table border="1" bgcolor="#FFFFE0" cellpadding="10" style="width:50%"><tr><td><pre> |
1223 | local lanes = require "lanes" | 1334 | local lanes = require "lanes" |
1224 | 1335 | ||
1225 | local linda = lanes.linda("my linda") | 1336 | local linda = lanes.linda{name = "my linda"} |
1226 | 1337 | ||
1227 | local function loop(max) | 1338 | local function loop(max) |
1228 | for i = 1, max do | 1339 | for i = 1, max do |
@@ -1260,7 +1371,7 @@ | |||
1260 | <li>Two producer-side methods: <tt>:send</tt> and <tt>:set</tt> (not out).</li> | 1371 | <li>Two producer-side methods: <tt>:send</tt> and <tt>:set</tt> (not out).</li> |
1261 | <li><tt>send</tt> allows for sending multiple values -atomically- to a given slot.</li> | 1372 | <li><tt>send</tt> allows for sending multiple values -atomically- to a given slot.</li> |
1262 | <li><tt>receive</tt> can wait for multiple slots at once.</li> | 1373 | <li><tt>receive</tt> can wait for multiple slots at once.</li> |
1263 | <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> | 1374 | <li><tt>receive_batched</tt> can be used to consume more than one value from a single slot, as in <tt>linda:receive_batched(1.0, "slot", 3, 6).</tt></li> |
1264 | <li><tt>restrict</tt> can restrain a particular slot to function either with <tt>send/receive</tt> or <tt>set/get</tt>.</li> | 1375 | <li><tt>restrict</tt> can restrain a particular slot to function either with <tt>send/receive</tt> or <tt>set/get</tt>.</li> |
1265 | <li>Individual slots' queue length can be limited, balancing speed differences in a producer/consumer scenario (making <tt>:send</tt> wait).</li> | 1376 | <li>Individual slots' queue length can be limited, balancing speed differences in a producer/consumer scenario (making <tt>:send</tt> wait).</li> |
1266 | <li><tt>tostring(linda)</tt> returns a string of the form <tt>"Linda: <opt_name>"</tt></li> | 1377 | <li><tt>tostring(linda)</tt> returns a string of the form <tt>"Linda: <opt_name>"</tt></li> |
@@ -1276,16 +1387,24 @@ | |||
1276 | </p> | 1387 | </p> |
1277 | 1388 | ||
1278 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1389 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1279 | h = lanes.linda([name],[group],[close_handler]) | 1390 | h = lanes.linda(table|nil) |
1280 | </pre></td></tr></table> | 1391 | </pre></td></tr></table> |
1281 | 1392 | ||
1282 | <p> | 1393 | <p> |
1283 | 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 /> | 1394 | Argument to <tt>lanes.linda()</tt> is either <tt>nil</tt> or a single table. The table may contain the following entries: |
1284 | Converting the linda to a string will yield the provided name prefixed by <tt>"Linda: "</tt>.<br /> | 1395 | <ul> |
1285 | 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 /> | 1396 | <li><tt>close_handler</tt>: a callable object (function or table/userdata with <tt>__call</tt> metamethod). If provided, and the linda is to-be-closed (Lua 5.4+), it will be called with all the provided arguments. For older Lua versions, its presence is ignored.</li> |
1286 | If <tt>opt_name</tt> is <tt>"auto"</tt>, Lanes will try to construct a name from the source location that called <tt>lanes.linda()</tt>. If that fails, the linda name will be <tt>"<unresolved>"</tt>.<br /> | 1397 | <li><tt>group</tt>: an integer between 0 and the number of Keeper states. Mandatory if Lanes is configured with more than one Keeper state. Group 0 is used by the internal timer linda.</li> |
1287 | If Lanes is configured with more than one Keeper state, <tt>group</tt> is mandatory.<br /> | 1398 | <li> |
1288 | 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. | 1399 | <tt>name</tt>: a string. Converting the linda to a string will yield the provided name prefixed by <tt>"Linda: "</tt>. |
1400 | If omitted or empty, it will evaluate to the string representation of a hexadecimal number uniquely representing that linda when the linda is converted to a string. The numeric value is the same as returned by <tt>linda:deep()</tt>.<br /> | ||
1401 | If <tt>"auto"</tt>, Lanes will try to construct a name from the source location that called <tt>lanes.linda()</tt>. If that fails, the linda name will be <tt>"<unresolved>"</tt>. | ||
1402 | </li> | ||
1403 | <li> | ||
1404 | <tt>wake_period</tt>: a number > 0 (unit: seconds). If provided, overrides <a href="#linda_wake_period"><tt>linda_wake_period</tt></a> provided to <a href="#initialization"><tt>lanes.configure()</tt></a>. | ||
1405 | </li> | ||
1406 | </ul> | ||
1407 | Unknown fields are silently ignored. | ||
1289 | </p> | 1408 | </p> |
1290 | 1409 | ||
1291 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1410 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
@@ -1349,12 +1468,12 @@ | |||
1349 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1468 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1350 | slot, val = h:receive([timeout_secs,] slot [, slot...]) | 1469 | slot, val = h:receive([timeout_secs,] slot [, slot...]) |
1351 | 1470 | ||
1352 | slot, val [, val...] = h:receive([timeout,] h.batched, slot, n_uint_min[, n_uint_max]) | 1471 | slot, val [, val...] = h:receive_batched([timeout,] slot, n_uint_min[, n_uint_max]) |
1353 | </pre></td></tr></table> | 1472 | </pre></td></tr></table> |
1354 | 1473 | ||
1355 | <p> | 1474 | <p> |
1356 | <tt>receive()</tt> raises an error if called when a restriction forbids its use on any provided slot.<br /> | 1475 | <tt>receive()</tt> and <tt>receive_batched()</tt> raise an error if called when a restriction forbids their use on any provided slot.<br /> |
1357 | In batched mode, <tt>receive()</tt> will raise an error if <tt>min_count < 1</tt> or <tt>max_count < min_count</tt>. | 1476 | <tt>receive_batched()</tt> will raise an error if <tt>min_count < 1</tt> or <tt>max_count < min_count</tt>. |
1358 | </p> | 1477 | </p> |
1359 | 1478 | ||
1360 | <p> | 1479 | <p> |