Skip to content

Commit 87d5251

Browse files
committed
Rework LockUnlockNoWaitTest to force lock fails
1 parent 0fbcbc1 commit 87d5251

File tree

1 file changed

+62
-25
lines changed

1 file changed

+62
-25
lines changed

src/lock/tests/LockManagerTest.cpp

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ BOOST_AUTO_TEST_CASE(LockUnlockWaitTest)
8989
const string lockManagerId(getUniqueId().c_str());
9090
auto lockManager = std::make_unique<LockManager>(lockManagerId, &config);
9191

92-
unsigned lockSuccess = 0u;
93-
std::atomic_uint lockFail = 0;
92+
std::atomic_uint lockSuccess = 0u;
93+
std::atomic_uint lockFail = 0u;
9494

9595
std::vector<std::thread> threads;
9696
std::latch latch(THREAD_COUNT);
@@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(LockUnlockWaitTest)
129129
thread.join();
130130

131131
BOOST_CHECK_EQUAL(lockFail.load(), 0u);
132-
BOOST_CHECK_EQUAL(lockSuccess, THREAD_COUNT * ITERATION_COUNT);
132+
BOOST_CHECK_EQUAL(lockSuccess.load(), THREAD_COUNT * ITERATION_COUNT);
133133

134134
lockManager.reset();
135135
}
@@ -138,46 +138,83 @@ BOOST_AUTO_TEST_CASE(LockUnlockWaitTest)
138138
BOOST_AUTO_TEST_CASE(LockUnlockNoWaitTest)
139139
{
140140
constexpr unsigned THREAD_COUNT = 8u;
141-
constexpr unsigned ITERATION_COUNT = 10'000u;
142-
143141
ConfigFile configFile(ConfigFile::USE_TEXT, "\n");
144142
Config config(configFile);
145143

146144
LockManagerTestCallbacks callbacks;
147145
const string lockManagerId(getUniqueId().c_str());
148146
auto lockManager = std::make_unique<LockManager>(lockManagerId, &config);
149147

150-
unsigned lockSuccess = 0u;
151-
std::atomic_uint lockFail = 0;
148+
std::atomic_uint lockSuccess = 0u;
149+
std::atomic_uint lockFail = 0u;
150+
151+
constexpr unsigned CONTENDER_COUNT = THREAD_COUNT - 1;
152152

153+
const UCHAR LOCK_KEY[] = {'1'};
153154
std::vector<std::thread> threads;
154-
std::latch latch(THREAD_COUNT);
155+
std::latch phase1Done(CONTENDER_COUNT);
156+
std::atomic_bool lockHeld = false;
157+
std::atomic_bool lockReleased = false;
155158

156-
for (unsigned threadNum = 0u; threadNum < THREAD_COUNT; ++threadNum)
159+
threads.emplace_back([&]() {
160+
FbLocalStatus statusVector;
161+
LOCK_OWNER_T ownerId = 1;
162+
SLONG ownerHandle = 0;
163+
164+
lockManager->initializeOwner(&statusVector, ownerId, LCK_OWNER_attachment, &ownerHandle);
165+
166+
const auto lockId = lockManager->enqueue(callbacks, &statusVector, 0,
167+
LCK_tra, LOCK_KEY, sizeof(LOCK_KEY), LCK_EX, nullptr, nullptr, 0, LCK_WAIT, ownerHandle);
168+
169+
BOOST_REQUIRE(lockId != 0);
170+
171+
lockHeld.store(true);
172+
phase1Done.wait();
173+
174+
lockManager->dequeue(lockId);
175+
lockReleased.store(true);
176+
177+
lockManager->shutdownOwner(callbacks, &ownerHandle);
178+
});
179+
180+
for (unsigned threadNum = 0; threadNum < CONTENDER_COUNT; ++threadNum)
157181
{
158182
threads.emplace_back([&, threadNum]() {
159-
const UCHAR LOCK_KEY[] = {'1'};
160183
FbLocalStatus statusVector;
161-
LOCK_OWNER_T ownerId = threadNum + 1;
184+
LOCK_OWNER_T ownerId = threadNum + 2;
162185
SLONG ownerHandle = 0;
163186

164187
lockManager->initializeOwner(&statusVector, ownerId, LCK_OWNER_attachment, &ownerHandle);
165188

166-
latch.arrive_and_wait();
189+
while (!lockHeld.load())
190+
std::this_thread::yield();
167191

168-
for (unsigned i = 0; i < ITERATION_COUNT; ++i)
192+
const auto firstLockId = lockManager->enqueue(callbacks, &statusVector, 0,
193+
LCK_tra, LOCK_KEY, sizeof(LOCK_KEY), LCK_EX, nullptr, nullptr, 0, LCK_NO_WAIT, ownerHandle);
194+
195+
if (firstLockId)
169196
{
170-
const auto lockId = lockManager->enqueue(callbacks, &statusVector, 0,
171-
LCK_tra, LOCK_KEY, sizeof(LOCK_KEY), LCK_EX, nullptr, nullptr, 0, LCK_NO_WAIT, ownerHandle);
197+
++lockSuccess;
198+
lockManager->dequeue(firstLockId);
199+
}
200+
else
201+
++lockFail;
172202

173-
if (lockId)
174-
{
175-
++lockSuccess;
176-
lockManager->dequeue(lockId);
177-
}
178-
else
179-
++lockFail;
203+
phase1Done.count_down();
204+
205+
while (!lockReleased.load())
206+
std::this_thread::yield();
207+
208+
const auto secondLockId = lockManager->enqueue(callbacks, &statusVector, 0,
209+
LCK_tra, LOCK_KEY, sizeof(LOCK_KEY), LCK_EX, nullptr, nullptr, 0, LCK_NO_WAIT, ownerHandle);
210+
211+
if (secondLockId)
212+
{
213+
++lockSuccess;
214+
lockManager->dequeue(secondLockId);
180215
}
216+
else
217+
++lockFail;
181218

182219
lockManager->shutdownOwner(callbacks, &ownerHandle);
183220
});
@@ -186,9 +223,9 @@ BOOST_AUTO_TEST_CASE(LockUnlockNoWaitTest)
186223
for (auto& thread : threads)
187224
thread.join();
188225

189-
BOOST_CHECK_GT(lockFail.load(), 0u);
190-
BOOST_CHECK_GT(lockSuccess, 0u);
191-
BOOST_CHECK_EQUAL(lockSuccess + lockFail, THREAD_COUNT * ITERATION_COUNT);
226+
BOOST_CHECK_GE(lockFail.load(), CONTENDER_COUNT);
227+
BOOST_CHECK_GT(lockSuccess.load(), 0u);
228+
BOOST_CHECK_EQUAL(lockSuccess.load() + lockFail.load(), CONTENDER_COUNT * 2);
192229

193230
lockManager.reset();
194231
}

0 commit comments

Comments
 (0)