diff options
author | snaury <snaury@ydb.tech> | 2022-08-24 11:26:42 +0300 |
---|---|---|
committer | snaury <snaury@ydb.tech> | 2022-08-24 11:26:42 +0300 |
commit | db2a536de1654fd420176ebde60a29222a546839 (patch) | |
tree | 44107ccbebf7cc25dada8e805ec787d332e9b67b | |
parent | aa6016e071468cd6678436437cd6386d32c0b481 (diff) | |
download | ydb-db2a536de1654fd420176ebde60a29222a546839.tar.gz |
Fix an early semaphore release before it is acquired
-rw-r--r-- | ydb/core/kesus/tablet/tablet_ut.cpp | 35 | ||||
-rw-r--r-- | ydb/core/kesus/tablet/tx_semaphore_release.cpp | 2 |
2 files changed, 36 insertions, 1 deletions
diff --git a/ydb/core/kesus/tablet/tablet_ut.cpp b/ydb/core/kesus/tablet/tablet_ut.cpp index 1cf1a80ca8e..d73b3c38053 100644 --- a/ydb/core/kesus/tablet/tablet_ut.cpp +++ b/ydb/core/kesus/tablet/tablet_ut.cpp @@ -1279,6 +1279,41 @@ Y_UNIT_TEST_SUITE(TKesusTest) { } } + Y_UNIT_TEST(TestSemaphoreReleaseReacquire) { + TTestContext ctx; + ctx.Setup(); + auto proxy = ctx.Runtime->AllocateEdgeActor(); + ctx.MustRegisterProxy(proxy, 1); + ctx.MustAttachSession(proxy, 1, 0, 30000); + ctx.MustAttachSession(proxy, 1, 0, 30000); + + for (int i = 0; i < 10; ++i) { + // Create and destroy semaphore several times to increment next ids + ctx.CreateSemaphore("Sem1", 1); + ctx.DeleteSemaphore("Sem1"); + } + + ctx.CreateSemaphore("Sem1", 1); + + // The first session owns semaphore immediately + ctx.SendAcquireSemaphore(111, proxy, 1, 1, "Sem1", 1); + ctx.ExpectAcquireSemaphoreResult(111, proxy, 1); + + // The second session tries to acquire semaphore, but releases immediately + ctx.SendAcquireSemaphore(222, proxy, 1, 2, "Sem1", 1, 10000); + ctx.ExpectAcquireSemaphorePending(222, proxy, 1); + ctx.MustReleaseSemaphore(333, proxy, 1, 2, "Sem1"); + ctx.ExpectAcquireSemaphoreResult(222, proxy, 1, Ydb::StatusIds::ABORTED); + + // The second session now tries to reacquire semaphore + ctx.SendAcquireSemaphore(444, proxy, 1, 2, "Sem1", 1, 10000); + ctx.ExpectAcquireSemaphorePending(444, proxy, 1); + + // When the first session releases semaphore it must be acquired by the second session + ctx.MustReleaseSemaphore(555, proxy, 1, 1, "Sem1"); + ctx.ExpectAcquireSemaphoreResult(444, proxy, 1); + } + Y_UNIT_TEST(TestSemaphoreSessionFailures) { TTestContext ctx; ctx.Setup(); diff --git a/ydb/core/kesus/tablet/tx_semaphore_release.cpp b/ydb/core/kesus/tablet/tx_semaphore_release.cpp index 326a3318613..ac166a33440 100644 --- a/ydb/core/kesus/tablet/tx_semaphore_release.cpp +++ b/ydb/core/kesus/tablet/tx_semaphore_release.cpp @@ -78,7 +78,7 @@ struct TKesusTablet::TTxSemaphoreRelease : public TTxBase { }); ReplyOk(); Self->DoDeleteSessionSemaphore(db, semaphore, waiter, Events); - session->WaitingSemaphores.erase(sessionId); + session->WaitingSemaphores.erase(semaphoreId); return true; } } |