From efb81b501adbbddf25615bbcc216bbbf3a3c8e0a Mon Sep 17 00:00:00 2001
From: Benoit Germain
Date: Wed, 23 Apr 2025 14:27:00 +0200
Subject: cancel_test() returns "soft"/"hard" instead of true
---
CHANGES | 1 +
docs/index.html | 23 +++++++++++++++++------
src/cancel.cpp | 6 +++++-
unit_tests/scripts/lane/cooperative_shutdown.lua | 1 -
4 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/CHANGES b/CHANGES
index ccfa923..4dc9d2d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -38,6 +38,7 @@ CHANGE 2: BGe 27-Nov-24
- Returns nil, error in case of problem.
- Forces lane function body must return a non-nil first value on success because of the above.
- lane:get_debug_threadname() renamed get_threadname().
+ - cancel_test() returns "soft"/"hard" instead of true when a cancellation request is active
- Lindas:
- lanes.linda()
- Arguments can be provided in any order.
diff --git a/docs/index.html b/docs/index.html
index e3e8c7a..e3fbd0b 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -71,7 +71,7 @@
- This document was revised on 21-Apr-25, and applies to version 4.0.0.
+ This document was revised on 23-Apr-25, and applies to version 4.0.0.
@@ -215,6 +215,7 @@
Inside the lane
+ - cancel_test(): check for cancellation requests
- lane_threadname(): read or change the name of the thread
- set_finalizer(): install a function called when the lane exits
@@ -1222,26 +1223,36 @@
First argument is a mode. It can be one of:
-
- "soft": Cancellation will only cause cancel_test() to return true, so that the lane can cleanup manually.
+ "soft": Cancellation will only cause cancel_test() to return "soft", so that the lane can cleanup manually.
Lindas will also check for cancellation inside blocking calls to early out based on their wake_period.
-
- "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).
+ "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).
+
+ If the lane isn't actually waiting on a Linda when the request is issued, a lane calling cancel_test() will see it return "hard".
+
wake_lane defaults to true, and timeout defaults to 0 if not specified.
-
"call", "ret", "line", "count": Asynchronously install the corresponding hook, then behave as "hard".
+
+ If the lane has the opportunity to call cancel_test() before the hook is invoked, calling cancel_test() will see it return "hard".
-
"all": Installs all hooks in one shot, just to be sure.
- If mode is not specified, it defaults to "hard".
+
+ 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.
-timeout is an optional number >= 0. Defaults to infinite if left unspecified or nil.
-
+
+ timeout is an optional number >= 0. Defaults to infinite if left unspecified or nil.
+
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.
diff --git a/src/cancel.cpp b/src/cancel.cpp
index 5bba9fc..ec9b6e4 100644
--- a/src/cancel.cpp
+++ b/src/cancel.cpp
@@ -133,7 +133,11 @@ static CancelOp WhichCancelOp(lua_State* const L_, StackIndex const idx_)
LUAG_FUNC(cancel_test)
{
CancelRequest const _test{ CheckCancelRequest(L_) };
- lua_pushboolean(L_, _test != CancelRequest::None);
+ if (_test == CancelRequest::None) {
+ lua_pushboolean(L_, 0);
+ } else {
+ luaG_pushstring(L_, (_test == CancelRequest::Soft) ? "soft" : "hard");
+ }
return 1;
}
diff --git a/unit_tests/scripts/lane/cooperative_shutdown.lua b/unit_tests/scripts/lane/cooperative_shutdown.lua
index 756e33c..0e30f91 100644
--- a/unit_tests/scripts/lane/cooperative_shutdown.lua
+++ b/unit_tests/scripts/lane/cooperative_shutdown.lua
@@ -23,7 +23,6 @@ end
local lane3 = function()
lane_threadname("lane3")
-- this one cooperates too, because of the hook cancellation modes that Lanes will be using
- -- but not with LuaJIT, because the function is compiled, and we don't call anyone, so no hook triggers
local fixture = require "fixture"
repeat until fixture.give_me_back(false)
end
--
cgit v1.2.3-55-g6feb