From 3f5c16116a3a7740ac4ac62b663661d772543c2e Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 10 Jun 2024 16:21:31 +0200 Subject: Replaced __lanesignore with __lanesconvert --- docs/index.html | 91 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 44 insertions(+), 47 deletions(-) (limited to 'docs') diff --git a/docs/index.html b/docs/index.html index 60f4970..24c7c52 100644 --- a/docs/index.html +++ b/docs/index.html @@ -546,7 +546,7 @@ - root level names, print, assert, unpack etc. + _G namespace (the default function environment): print, assert, dofile, etc. @@ -1150,13 +1150,13 @@

Lindas

- Communications between lanes is completely detached from the lane handles themselves. By itself, a lane can only provide return values once it's finished, or throw an error. + 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 parameters, 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 in parallel. 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.

@@ -1212,51 +1212,59 @@
 
 
 	h = lanes.linda([opt_name, [opt_group]])
+
- true|lanes.cancel_error = h:send([timeout_secs,] key, ...) +

+ Converting the Linda to a string will yield the provided name prefixed by "Linda: ".
+ If opt_name 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 linda:deep().
+ If opt_name is "auto", Lanes will try to construct a name from the source location that called lanes.linda(). If that fails, the Linda name will be "<unresolved>". +

- key, val = h:receive([timeout_secs,] key [, key...]) +
+	true|lanes.cancel_error = h:limit(key, n_uint)
+
- key, val [, val...] = h:receive(timeout, h.batched, key, n_uint_min[, n_uint_max]) +

+ By default, queue sizes are unlimited but limits can be enforced using the limit() method. This can be useful to balance execution speeds in a producer/consumer scenario. nil removes the limit.
+ A limit of 0 is allowed to block everything.
+ If the key was full but the limit change added some room, limit() returns true and the Linda is signalled so that send()-blocked threads are awakened.
+

- true|lanes.cancel_error = h:limit(key, n_uint) +
+	true|lanes.cancel_error = h:send([timeout_secs,] key, ...)
 

- Converting the Linda to a string will yield the provided name prefixed by "Linda: ".
- If opt_name 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 linda:deep().
- If opt_name is "auto", Lanes will try to construct a name from the source location that called lanes.linda(). If that fails, the Linda name will be "<unresolved>". + Timeouts are given in seconds (>= 0, millisecond accuracy) or nil. Timeout can be omitted only if the first key is not a number (then it is equivalent to an infinite duration).
+ Each key acts as a FIFO queue. There is no limit to the number of keys a Linda may contain. Different Lindas can have identical keys, which are totally unrelated.

- Timeouts are given in seconds (>= 0, millisecond accuracy) or nil. Timeout can be omitted only if the first key is not a number (then it's equivalent to an infinite duration). + If no data is provided after the key, send() raises an error.
+ Also, if linda.null or lanes.null is sent as data in a Linda, it will be read as a nil.
+ send() returns true if the sending succeeded, and false if the queue limit was met, and the queue did not empty enough during the given timeout.
+ send() returns lanes.cancel_error if interrupted by a soft cancel request.

+
+	key, val = h:receive([timeout_secs,] key [, key...])
+
+	key, val [, val...] = h:receive(timeout, h.batched, key, n_uint_min[, n_uint_max])
+
+ +

The send() and receive() methods use Linda keys as FIFO stacks (first in, first out).
- By default, stack sizes are unlimited but limits can be enforced using the limit() method. This can be useful to balance execution speeds in a producer/consumer scenario. nil removes the limit.
- A limit of 0 is allowed to block everything.
- If the key was full but the limit change added some room, limit() returns true and the Linda is signalled so that send()-blocked threads are awakened.
In batched mode, linda:receive() will raise an error if min_count < 1 or max_count < min_count.

- Note that any number of lanes can be reading or writing a Linda. There can be many producers, and many consumers. It's up to you. + 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.

Hard cancellation will cause pending Linda operations to abort execution of the lane through a cancellation error. This means that you have to install a finalizer in your lane if you want to run some code in that situation.

-

- send() returns true if the sending succeeded, and false if the queue limit was met, and the queue did not empty enough during the given timeout. -
- send() returns lanes.cancel_error if interrupted by a soft cancel request. -
- If no data is provided after the key, send() raises an error. -
- Also, if linda.null or lanes.null is sent as data in a Linda, it will be read as a nil. -

-

Equally, receive() returns a key and the value extracted from it. Note that nils can be sent and received; the key value will tell it apart from a timeout.
receive() returns nil, lanes.cancel_error if interrupted by a hard cancel request.
@@ -1558,14 +1566,22 @@ On the other side, you need to use a common Linda for waiting for multiple keys. 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.

  • - Full userdata can be passed only if it's prepared using the deep userdata system, which handles its lifespan management + Full userdata can be passed only if it is prepared using the deep userdata system, which handles its lifespan management
    • In particular, lane handles cannot be passed between lanes.
    • Lanes can either throw an error or attempt a light userdata demotion.
  • 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.
  • -
  • If the metatable contains __lanesignore, the object is skipped and nil is transfered instead.
  • +
  • + If the metatable contains __lanesconvert, the object is converted as follows depending on the value: +
      +
    • lanes.null: The value is converted to nil.
    • +
    • "decay": The value is converted to a light userdata obtained from lua_topointer().
    • +
    • A function: The function is called as o:__lanesconvert(string), where the argument is either "keeper" or "regular", depending on the type of destination. Its (single) return value is the result of the conversion.
    • +
    • Any other value raises an error.
    • +
    +
  • @@ -1573,26 +1589,7 @@ On the other side, you need to use a common Linda for waiting for multiple keys.

    Notes about passing C functions

    - Originally, a C function was copied from one Lua state to another as follows: -

    - -
    -	// expects a C function on top of the source Lua stack
    -	copy_func(lua_State *dest, lua_State* source)
    -	{
    -		// extract C function pointer from source
    -		lua_CFunction func = lua_tocfunction(source, -1);
    -		// transfer upvalues
    -		int nup = transfer_upvalues(dest, source);
    -		// dest Lua stack contains a copy of all upvalues
    -		lua_pushcfunction(dest, func, nup);
    -	}
    -
    - -

    - This has the main drawback of not being LuaJIT-compatible, because some functions registered by LuaJIT are not regular C functions, but specially optimized implementations. As a result, lua_tocfunction() returns nullptr for them. -
    - Therefore, Lanes no longer transfers functions that way. Instead, functions are transfered as follows (more or less): + Functions are transfered as follows (more or less):

    -- 
    cgit v1.2.3-55-g6feb