Skip to content

Commit

Permalink
Add missing lock for a cond var; add one more unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeyRyabinin committed Oct 18, 2023
1 parent 4e363b9 commit 7f023f5
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ namespace Aws
m_logsProcessed--;
if(m_logsProcessed == 0 && m_stopLogging)
{
std::unique_lock<std::mutex> lock(m_stopMutex);
m_stopSignal.notify_all();
}
}
Expand Down
103 changes: 103 additions & 0 deletions tests/aws-cpp-sdk-core-tests/utils/threading/ReaderWriterLockTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,106 @@ TEST_F(ReaderWriterLockTest, NoReadersMultipleWriters)

ASSERT_EQ(originalLength + THREADS_NUM * ITERATIONS, resource.length());
}

TEST_F(ReaderWriterLockTest, Explosive)
{
const char sharedBufferOriginal[] = "It's still Day One";
char sharedBuffer[] = "It's still Day One";
const size_t sharedBufferSz = strlen(sharedBuffer);
Aws::Utils::Threading::ReaderWriterLock sharedBufferLock;

std::atomic<bool> readersRunning;
readersRunning.store(true);
std::atomic<size_t> readersRunCount;
readersRunCount.store(0);
auto reader = [&]()
{
Aws::Utils::Threading::ReaderLockGuard guard(sharedBufferLock);

readersRunCount++;
EXPECT_STREQ(sharedBufferOriginal, sharedBuffer);
};

auto slowWriter = [&]()
{
Aws::Utils::Threading::WriterLockGuard guard(sharedBufferLock);
for(size_t i = 0; i < sharedBufferSz; ++i)
{
sharedBuffer[i] = 'B';
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

for(size_t i = 0; i < sharedBufferSz; ++i)
{
sharedBuffer[i] = sharedBufferOriginal[i];
}
};

static const size_t READER_COUNT = 8;
Aws::Vector<std::future<bool>> readerFutures(READER_COUNT);
std::atomic<size_t> readersStarted;
readersStarted = 0;
for(size_t i = 0; i < READER_COUNT/2; ++i) {
readerFutures[i] = std::async(std::launch::async,
[&]() -> bool {
readersStarted++;
while(readersRunning)
{
reader();
}
return true;
});
}

while(readersStarted.load() != READER_COUNT/2)
{
continue;
}

const size_t readersRunCountBeforeWriter = readersRunCount;
ASSERT_GE(readersRunCountBeforeWriter, READER_COUNT);

static const size_t WRITER_COUNT = 3;
Aws::Vector<std::future<bool>> writerFutures(WRITER_COUNT);
static const size_t WRITERS_REPEAT = 4;
for(size_t i = 0; i < WRITER_COUNT; ++i) {
writerFutures[i] = std::async(std::launch::async,
[&]() -> bool {
for(size_t writeRepeat = 0; writeRepeat < WRITERS_REPEAT; ++writeRepeat)
{
slowWriter();
}
return true;
});
}

for(size_t i = READER_COUNT/2; i < READER_COUNT; ++i) {
readerFutures[i] = std::async(std::launch::async,
[&]() -> bool {
readersStarted++;
while(readersRunning)
{
reader();
}
return true;
});
}
while(readersStarted.load() != READER_COUNT)
{
continue;
}

for(size_t i = 0; i < WRITER_COUNT; ++i)
{
bool success = writerFutures[i].get();
ASSERT_TRUE(success);
}
std::this_thread::sleep_for(std::chrono::milliseconds(200));
readersRunning.store(false);

for(size_t i = 0; i < READER_COUNT; ++i)
{
bool success = readerFutures[i].get();
ASSERT_TRUE(success);
}
}

0 comments on commit 7f023f5

Please sign in to comment.