From 73813e8fd4104ba4cc56fc66180fb8408f289ba0 Mon Sep 17 00:00:00 2001
From: Benoit Germain Features:
-
@@ -316,7 +316,7 @@
"libc"/"allocator"
-
extern void LANES_API luaopen_lanes_embedded(lua_State* L, lua_CFunction _luaopen_lanes);
+ LANES_API void luaopen_lanes_embedded(lua_State* L_, lua_CFunction luaopen_lanes_);
- Controls which allocator is used for Lanes internal allocations (for Keeper state, Linda and lane management).
+ Controls which allocator is used for Lanes internal allocations (for Keeper state, linda and lane management).
If "libc", Lanes uses realloc and free.
If "allocator", Lanes uses whatever was obtained from the "allocator" setting.
This option is mostly useful for embedders that want control all memory allocations, but have issues when Lanes tries to use the Lua State allocator for internal purposes (especially with LuaJIT).
@@ -342,9 +342,9 @@
integer in [0,100]
- Controls the number of "user" Keeper state used internally by Linda) objects to transfer data between lanes. Default is 0.
@@ -436,7 +436,7 @@
- Lanes always creates at least one keeper state (of group 0 for the internal timer Linda. If nb_user_keepers is 0, the other lindas you create will share this keeper by necessity.
- If there is more than one Keeper state (in total), Linda creation must specify the group it belongs to.
+ Controls the number of "user" Keeper state used internally by linda) objects to transfer data between lanes. Default is 0.
+ Lanes always creates at least one keeper state (of group 0 for the internal timer linda. If nb_user_keepers is 0, the other lindas you create will share this keeper by necessity.
+ If there is more than one Keeper state (in total), linda creation must specify the group it belongs to.
- Once Lanes is configured, one should register with Lanes the modules exporting functions that will be transferred either during lane generation or through Lindas.
+ Once Lanes is configured, one should register with Lanes the modules exporting functions that will be transferred either during lane generation or through lindas.
Use lanes.require() for this purpose. This will call the original require(), then add the result to the lookup databases.
@@ -469,7 +469,7 @@
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).
Only the last registered finalizer is kept. It can be cleared by passing nil or nothing.
- The finalizer is called unprotected from inside __gc metamethod of Lane's Universe. Therefore, if your finalizer raises an error, Lua rules regarding errors in finalizers apply normally.
+ The finalizer is called unprotected from inside __gc metamethod of Lanes's Universe. Therefore, if your finalizer raises an error, Lua rules regarding errors in finalizers apply normally.
The installed function is called after all free-running lanes got a chance to terminate (see shutdown_timeout), but before lindas become unusable.
The finalizer receives a single argument, a bool indicating whether some Lanes are still running or not at that point. It is possible to inspect them with tracking.
If there are still running lanes when the finalizer returns: Lanes will throw a C++ std::logic_error if the finalizer returned "throw". Any other value will cause Lanes to freeze forever.
@@ -508,7 +508,7 @@
The function returned by lanes.gen() 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.
- Alternatively, lane_func may be a string, in which case it will be compiled in the lane. This was to be able to launch lanes with older versions of LuaJIT, which didn't not support lua_dump, used internally to transfer functions to the lane.
+ Alternatively, lane_func 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 lua_dump, used internally to transfer functions to the lane.
@@ -797,7 +797,7 @@
- It is possible to have the Lane body run inside the lane as a coroutine. For this, just use lanes.coro() instead of lanes.gen(). + It is possible to have the lane body run inside the lane as a coroutine. For this, just use lanes.coro() instead of lanes.gen().
@@ -921,7 +921,7 @@ | - Running, not suspended on a Linda call, or yielded on a coroutine.yield() call. + Running, not suspended on a linda call, or yielded on a coroutine.yield() call. | |
- Waiting at a Linda :receive() or :send() + Waiting at a linda :receive() or :send() | ||
- If you want to wait for multiple lanes to finish (any of a set of lanes), use a Linda object. Give each lane a specific id, and send that id over a Linda once that thread is done (as the last thing you do). + If you want to wait for multiple lanes to finish (any of a set of lanes), use a linda object. Give each lane a specific id, and send that id over a linda once that thread is done (as the last thing you do).
@@ -1112,7 +1112,7 @@ "soft": Cancellation will only cause cancel_test() to return true, so that the lane can cleanup manually. + "hard": waits for the request to be processed, or a timeout to occur. linda operations detecting the cancellation request will raise a special cancellation error (meaning they won't return in that case). wake_lane defaults to true, and timeout defaults to 0 if not specified.
Returns true, lane_h.status if lane was already done (in "done", "error" or "cancelled" status), or the cancellation was fruitful within timeout_secs timeout period.
Cancellation is tested before going to sleep in receive() or send() calls and after executing cancelstep Lua statements. A pending receive()or send() call is awakened.
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 Linda objects, which are - deep userdata instances. They can be provided to a lane as startup arguments, upvalues or in some other Linda's message. + Needs to communicate during runtime are handled by linda objects, which are + deep userdata instances. They can be provided to a lane as startup arguments, upvalues or in some other linda's message. - 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. + 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.
- Characteristics of the Lanes implementation of Lindas are: + Characteristics of the Lanes implementation of lindas are:
Arguments to lanes.linda() 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).
- 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 Linda used for timers (this Linda exists even when timers aren't enabled).
+ 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 linda used for timers (this linda exists even when timers aren't enabled).
Default duration is 0, which should only cause a thread context switch. |
- Returns the current value of the clock used by timers and Linda objects. + Returns the current value of the clock used by timers and linda objects.
@@ -1575,7 +1575,7 @@ On the other side, you need to use a common Linda for waiting for multiple keys.
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 M=N=1 for a critical section lock (only one lane allowed to enter).
- When passsing "try" as second argument when acquiring, then lock_func operates on the Linda with a timeout of 0 to emulate a TryLock() operation. If locking fails, lock_func returns false. "try" is ignored when releasing (as it it not expected to ever have to wait unless the acquisition/release pairs are not properly matched).
+ When passsing "try" as second argument when acquiring, then lock_func operates on the linda with a timeout of 0 to emulate a TryLock() operation. If locking fails, lock_func returns false. "try" is ignored when releasing (as it it not expected to ever have to wait unless the acquisition/release pairs are not properly matched).
Upon successful lock/unlock, lock_func returns true (always the case when block-waiting for completion).
- Data passed between lanes (either as starting arguments, return values, upvalues or via Lindas) must conform to the following: + Data passed between lanes (either as starting arguments, return values, upvalues or via lindas) must conform to the following:
- The mechanism Lanes uses for sharing Linda handles between separate Lua states can be used for custom userdata as well. Here's what to do. + The mechanism Lanes uses for sharing linda handles between separate Lua states can be used for custom userdata as well. Here's what to do.
- Deep userdata in transit inside Keeper states (sent in a Linda but not yet consumed) don't call deleteDeepObjectInternal and aren't considered by reference counting. The rationale is the following:
+ Deep userdata in transit inside Keeper states (sent in a linda but not yet consumed) don't call deleteDeepObjectInternal and aren't considered by reference counting. The rationale is the following:
If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0.
OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's factory() interface is never accessed from a keeper state.
Therefore, Lanes can just call deleteDeepObjectInternal when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in Keeper states now hold stale pointers.
@@ -1866,7 +1866,7 @@ static MyDeepFactory g_MyDeepFactory;
- 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 Linda. + 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 linda.
@@ -1894,12 +1894,12 @@ static MyDeepFactory g_MyDeepFactory;
Cancellation of lanes uses the Lua error mechanism with a special lightuserdata error sentinel. - If you use pcall 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. + If you use pcall 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.
-- cgit v1.2.3-55-g6feb