@@ -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)
138138BOOST_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