From 4f97720e4c3944ccf9b9742028dc697c2dd94c5a Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Thu, 26 Feb 2026 11:02:55 +0100 Subject: change cancel_test() to raise cancel_error on hard-cancels by default --- unit_tests/scripts/_utils.lua | 2 +- unit_tests/scripts/_utils54.lua | 2 +- unit_tests/scripts/lane/cooperative_shutdown.lua | 2 +- unit_tests/scripts/lane/tasking_cancelling.lua | 16 ++++++++++++---- 4 files changed, 15 insertions(+), 7 deletions(-) (limited to 'unit_tests/scripts') diff --git a/unit_tests/scripts/_utils.lua b/unit_tests/scripts/_utils.lua index 9f46237..365fd10 100644 --- a/unit_tests/scripts/_utils.lua +++ b/unit_tests/scripts/_utils.lua @@ -76,7 +76,7 @@ local yield_one_by_one = function(...) local _val = select(_i, ...) PRINT("yielding #", _i, _val) local _ack = coroutine.yield(_val) - if cancel_test and cancel_test() then -- cancel_test does not exist when run immediately (not in a Lane) + if cancel_test and cancel_test(true) then -- cancel_test does not exist when run immediately (not in a Lane) return "cancelled!" end -- of course, if we are cancelled, we were not resumed, and yield() didn't return what we expect diff --git a/unit_tests/scripts/_utils54.lua b/unit_tests/scripts/_utils54.lua index a511563..629f5c5 100644 --- a/unit_tests/scripts/_utils54.lua +++ b/unit_tests/scripts/_utils54.lua @@ -20,7 +20,7 @@ utils.yielder_with_to_be_closed = function(out_linda_, wait_) local n = 1 while true do coroutine.yield("I yield!", n) - if cancel_test and cancel_test() then -- cancel_test does not exist when run immediately (not in a Lane) + if cancel_test and cancel_test(true) then -- cancel_test does not exist when run immediately (not in a Lane) return "I am cancelled" end n = n + 1 diff --git a/unit_tests/scripts/lane/cooperative_shutdown.lua b/unit_tests/scripts/lane/cooperative_shutdown.lua index 0a0943e..3329e9d 100644 --- a/unit_tests/scripts/lane/cooperative_shutdown.lua +++ b/unit_tests/scripts/lane/cooperative_shutdown.lua @@ -7,7 +7,7 @@ local lane1 = function() -- loop breaks on soft cancellation request repeat lanes.sleep(0) - until cancel_test() + until cancel_test(true) print "lane1 cancelled" end diff --git a/unit_tests/scripts/lane/tasking_cancelling.lua b/unit_tests/scripts/lane/tasking_cancelling.lua index 395bee5..f7ad729 100644 --- a/unit_tests/scripts/lane/tasking_cancelling.lua +++ b/unit_tests/scripts/lane/tasking_cancelling.lua @@ -29,24 +29,32 @@ local no_cancel_result = no_cancel_lane[1] assert(no_cancel_result == false, "cancel_test() should return boolean false, got " .. type(no_cancel_result) .. ": " .. tostring(no_cancel_result)) -- cancellation of cooperating lanes -local cooperative = function() +-- query_only: if true, pass true to cancel_test() so that hard cancel returns "hard" instead of raising +local cooperative = function(query_only_) local fixture = assert(require "fixture") local which_cancel repeat fixture.block_for(0.2) - which_cancel = cancel_test() + which_cancel = cancel_test(query_only_) until which_cancel return which_cancel end --- soft and hard are behaviorally equivalent when no blocking linda operation is involved +-- for soft cancel, cancel_test() returns "soft" so the lane exits the loop and returns it local cooperative_lane_soft = lanes_gen("*", { name = 'auto' }, cooperative)() local a, b = cooperative_lane_soft:cancel("soft", 0) -- issue request, do not wait for lane to terminate assert(a == false and b == "timeout", "got " .. tostring(a) .. " " .. tostring(b)) assert(cooperative_lane_soft[1] == "soft", "cancel_test() should return \"soft\", got " .. type(cooperative_lane_soft[1]) .. ": " .. tostring(cooperative_lane_soft[1])) -- return value of the lane body is the value returned by cancel_test() +-- for hard cancel, cancel_test() raises cancel_error, so the lane ends up in the cancelled state local cooperative_lane_hard = lanes_gen("*", { name = 'auto' }, cooperative)() local c, d = cooperative_lane_hard:cancel("hard", 0) -- issue request, do not wait for lane to terminate assert(c == false and d == "timeout", "got " .. tostring(c) .. " " .. tostring(d)) -assert(cooperative_lane_hard[1] == "hard", "cancel_test() should return \"hard\", got " .. type(cooperative_lane_hard[1]) .. ": " .. tostring(cooperative_lane_hard[1])) -- return value of the lane body is the value returned by cancel_test() +assert(cooperative_lane_hard[1] == nil, "cancelled lane first result should be nil, got " .. type(cooperative_lane_hard[1]) .. ": " .. tostring(cooperative_lane_hard[1])) +assert(cooperative_lane_hard[2] == lanes.cancel_error, "cancelled lane second result should be cancel_error") +-- for hard cancel with query_only=true, cancel_test(true) returns "hard" so the lane exits the loop and returns it +local cooperative_lane_hard_query = lanes_gen("*", { name = 'auto' }, cooperative)(true) +local e, f = cooperative_lane_hard_query:cancel("hard", 0) -- issue request, do not wait for lane to terminate +assert(e == false and f == "timeout", "got " .. tostring(e) .. " " .. tostring(f)) +assert(cooperative_lane_hard_query[1] == "hard", "cancel_test(true) should return \"hard\", got " .. type(cooperative_lane_hard_query[1]) .. ": " .. tostring(cooperative_lane_hard_query[1])) -- ################################################################################################## -- cgit v1.2.3-55-g6feb