From 13f7f505375f7c1afd3a7e479a64cc147501b01d Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Tue, 7 May 2024 17:56:10 +0200 Subject: Linda API changes * timeout clarifications (negative values are no longer accepted, use nil instead) * linda(send, linda.null, key, ...) removed, if you want to send a nil, just do it as usual --- docs/index.html | 51 +++++---- src/cancel.cpp | 35 +++--- src/cancel.h | 2 +- src/lanes.cpp | 46 ++++---- src/lanes.lua | 17 +-- src/lanes_private.h | 2 +- src/linda.cpp | 25 ++--- src/lindafactory.cpp | 1 + src/universe.cpp | 3 +- tests/basic.lua | 296 ++++++++++++++++++++++++++------------------------- 10 files changed, 250 insertions(+), 228 deletions(-) diff --git a/docs/index.html b/docs/index.html index e811074..3c9cbcf 100644 --- a/docs/index.html +++ b/docs/index.html @@ -953,26 +953,29 @@

- Waits until the lane finishes, or timeout seconds have passed. Returns nil, "timeout" on timeout, nil,err,stack_tbl if the lane hit an error, nil, "killed" if forcefully killed, or the return values of the lane. + timeout is an optional number >= 0 (the default if unspecified). +
+ Waits until the lane finishes, or timeout seconds have passed. +
+ Returns nil, "timeout" on timeout, nil,err,stack_tbl if the lane hit an error, nil, "killed" if forcefully killed, or the return values of the lane. +
Unlike in reading the results in table fashion, errors are not propagated.

stack_tbl is a table describing where the error was thrown.
- In "extended" mode, stack_tbl is an array of tables containing info gathered with lua_getinfo() ("source","currentline","name","namewhat","what"). + In "extended" mode, stack_tbl is an array of tables containing info gathered with lua_getinfo() ("source","currentline","name","namewhat","what").
- In "basic mode", stack_tbl is an array of "<filename>:<line>" strings. Use table.concat() to format it to your liking (or just ignore it). + In "basic" mode, stack_tbl is an array of "<filename>:<line>" strings. Use table.concat() to format it to your liking (or just ignore it).

- If you use :join, make sure your lane main function returns a non-nil value so you can tell timeout and error cases apart from succesful return (using the .status property may be risky, since it might change between a timed out join and the moment you read it). + If you use :join(), make sure your lane main function returns a non-nil value so you can tell timeout and error cases apart from succesful return (using the .status property may be risky, since it might change between a timed out join and the moment you read it).

-

-
-	require "lanes".configure()
+	local lanes = require "lanes".configure()
 
 	f = lanes.gen(function() error "!!!" end)
 	a = f(1)
@@ -990,7 +993,7 @@
 

-	require "lanes".configure()
+	local lanes = require "lanes".configure()
 
 	local sync_linda = lanes.linda()
 	f = lanes.gen(function() dostuff() sync_linda:send("done", true) end)
@@ -1012,7 +1015,10 @@
 

- cancel() sends a cancellation request to the lane.
+ timeout is an optional number >= 0. Defaults to 0 if left unspecified or nil. +
+ cancel() sends a cancellation request to the lane. +
First argument is a mode can be one of "hard", "soft", "call", "ret", "line", "count". If mode is not specified, it defaults to "hard". If wake_lane is true, the lane is also signalled so that execution returns from any pending linda operation. Linda operations detecting the cancellation request return lanes.cancel_error. @@ -1056,17 +1062,17 @@

- The error call is used for throwing exceptions in Lua. What Lua does not offer, however, is scoped finalizers + The regular Lua error function is usable in lanes for throwing exceptions. What Lua does not offer, however, is scoped finalizers that would get called when a certain block of instructions gets exited, whether through peaceful return or abrupt error.

- Since 2.0.3, Lanes registers a function set_finalizer in the lane's Lua state for doing this. + Lanes registers a function set_finalizer 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.

- An error in a finalizer itself overrides the state of the regular chunk (in practise, it would be highly preferable not to have errors in finalizers). If one finalizer errors, the others may not get called. + An error in a finalizer itself overrides the state of the regular chunk (in practice, it would be highly preferable not 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).

@@ -1103,18 +1109,18 @@

-	require "lanes".configure()
+	local lanes = require "lanes".configure()
 
-	local linda = lanes.linda()
+	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
+			linda:send("x", i)    -- linda as upvalue of loop()
 		end
 	end
 
-	a = lanes.gen("", loop)(10000)
+	lane_h = lanes.gen("", loop)(10000)
 
 	while true do
 		local key, val = linda:receive(3.0, "x")    -- timeout in seconds
@@ -1124,6 +1130,8 @@
 		end
 		print(tostring(linda) .. " received: " .. val)
 	end
+
+	lane_h:join()
 

@@ -1147,7 +1155,7 @@
 	h = lanes.linda([opt_name, [opt_group]])
 
-	[true|lanes.cancel_error] = h:send([timeout_secs,] [h.null,] key, ...)
+	[true|lanes.cancel_error] = h:send([timeout_secs,] key, ...)
 
 	[key, val]|[lanes.cancel_error] = h:receive([timeout_secs,] key [, ...])
 
@@ -1157,10 +1165,11 @@
 

- The send() and receive() methods use Linda keys as FIFO stacks (first in, first out). Timeouts are given in seconds (millisecond accuracy). If using numbers as the first Linda key, one must explicitly give nil as the timeout parameter to avoid ambiguities. + 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).

+ 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. Any negative value removes the limit.
A limit of 0 is allowed to block everything. @@ -1181,7 +1190,7 @@
send() returns lanes.cancel_error if interrupted by a soft cancel request.
- If no data is provided after the key, send() raises an error. If provided with linda.null or lanes.null before the actual key and there is no data to send, send() sends a single nil. + 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.

@@ -1395,7 +1404,7 @@ events to a common Linda, but... :).

-	void = lanes.sleep(['indefinitely'|seconds|false])
+	void = lanes.sleep(['indefinitely'|seconds|nil])
 

@@ -1775,7 +1784,7 @@ static MyDeepFactory g_MyDeepFactory;