aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnaury <snaury@ydb.tech>2022-08-24 11:26:42 +0300
committersnaury <snaury@ydb.tech>2022-08-24 11:26:42 +0300
commitdb2a536de1654fd420176ebde60a29222a546839 (patch)
tree44107ccbebf7cc25dada8e805ec787d332e9b67b
parentaa6016e071468cd6678436437cd6386d32c0b481 (diff)
downloadydb-db2a536de1654fd420176ebde60a29222a546839.tar.gz
Fix an early semaphore release before it is acquired
-rw-r--r--ydb/core/kesus/tablet/tablet_ut.cpp35
-rw-r--r--ydb/core/kesus/tablet/tx_semaphore_release.cpp2
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;
}
}