From e79953ff093c0518975111c69d16e97ccf966e20 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 15 Apr 2024 12:21:27 +0200 Subject: fix keeper state stack accumulating garbage in case of transfer errors --- CHANGES | 3 +++ Makefile | 1 + src/keeper.c | 4 +++- src/linda.c | 4 ++++ tests/deadlock.lua | 2 +- 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 34bd2d9..91849d7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ CHANGES: +CHANGE 161: BGe 15-Apr-24 + * fix keeper state stack accumulating garbage in case of transfer errors + CHANGE 160: BGe 11-Apr-24 * add manual control over GC behavior in keeper states * update a bunch of test scripts diff --git a/Makefile b/Makefile index 08888e4..9939f73 100644 --- a/Makefile +++ b/Makefile @@ -77,6 +77,7 @@ test: $(MAKE) basic $(MAKE) cancel $(MAKE) cyclic + $(MAKE) deadlock $(MAKE) errhangtest $(MAKE) fibonacci $(MAKE) fifo diff --git a/src/keeper.c b/src/keeper.c index a1505b7..1522718 100644 --- a/src/keeper.c +++ b/src/keeper.c @@ -810,7 +810,9 @@ int keeper_call( Universe* U, lua_State* K, keeper_api_t func_, lua_State* L, vo int const Ktos = lua_gettop( K); int retvals = -1; - STACK_GROW( K, 2); + // if we didn't do anything wrong, the keeper stack should be clean + ASSERT_L(Ktos == 0); + STACK_GROW(K, 2); PUSH_KEEPER_FUNC( K, func_); diff --git a/src/linda.c b/src/linda.c index 2128520..d92f5f2 100644 --- a/src/linda.c +++ b/src/linda.c @@ -90,12 +90,16 @@ LUAG_FUNC( linda_protected_call) Keeper* K = keeper_acquire( linda->U->keepers, LINDA_KEEPER_HASHSEED(linda)); lua_State* KL = K ? K->L : NULL; // need to do this for 'STACK_CHECK' if( KL == NULL) return 0; + // if we didn't do anything wrong, the keeper stack should be clean + ASSERT_L(lua_gettop(KL) == 0); // retrieve the actual function to be called and move it before the arguments lua_pushvalue( L, lua_upvalueindex( 1)); lua_insert( L, 1); // do a protected call rc = lua_pcall( L, lua_gettop( L) - 1, LUA_MULTRET, 0); + // whatever happens, the keeper state stack must be empty when we are done + lua_settop(KL, 0); // release the keeper keeper_release( K); diff --git a/tests/deadlock.lua b/tests/deadlock.lua index 73d7ccb..c85d99f 100644 --- a/tests/deadlock.lua +++ b/tests/deadlock.lua @@ -1,7 +1,7 @@ -- this script tests the fix of a bug that could cause the mutex of a keeper state to remain locked -- see https://github.com/LuaLanes/lanes/commit/0cc1c9c9dcea5955f7dab921d9a2fff78c4e1729 -local lanes = require('lanes').configure() +local lanes = require('lanes').configure{with_timers=false} local linda = lanes.linda "deadlock_linda" print "let's begin" -- cgit v1.2.3-55-g6feb