Unexpected behavior of std::shared_lock<std::shared_mutex>

phatpaul
Posts: 115
Joined: Fri Aug 24, 2018 1:14 pm

Unexpected behavior of std::shared_lock<std::shared_mutex>

Postby phatpaul » Fri Jun 20, 2025 6:52 pm

My goal is to be able to write C++ code that uses scoped lock objects like this:

Code: Select all

if (auto dbAccess = MyConfigDbManager::getInstance().getReadAccess()) // get scoped read lock
{
    // Got a read lock. Do something with the protected object, i.e.
    dbAccess->doSomething();
    // when this block ends and dbAccess goes out of scope, the lock is released automatically.
}
else
{
     ESP_LOGE(TAG, "failed to get read lock.");
}
You can see my LockableObject class implementation here: https://github.com/phatpaul/demo-cpp-sc ... Object.hpp

In the case of getReadAccess(), I'm using std::shared_lock<std::shared_mutex> to implement the lock because I want multiple threads to be able to get a read lock simultaneously.
But for getWriteAccess(), I'm using std::unique_lock<std::shared_mutex> so that it is exclusive. I.e. only 1 thread can have a write lock, and there can be no read locks active when a write lock is active.

It works >99% of the time, and I have implemented some unit tests here: https://github.com/phatpaul/demo-cpp-sc ... d-lock.cpp

But occasionally, a GetReadAccess() fails unexpectedly. I know that there are no write locks during this time.
I created this GitHub repo to demonstrate the issue. https://github.com/phatpaul/demo-cpp-sc ... k-esp-idf/
I hope someone can help me track down the cause of this bug. I have tested it on both IDF versions 4.4.8 and 5.4.1 with the same behavior.

phatpaul
Posts: 115
Joined: Fri Aug 24, 2018 1:14 pm

Re: Unexpected behavior of std::shared_lock<std::shared_mutex>

Postby phatpaul » Wed Sep 03, 2025 8:11 pm

Solved with short but non-zero blocking timeout!

After further digging, the issue seems to be contention on accessing the mutex object by multiple readers at the same time. It is fixed by adding a very short but non-zero blocking timeout to aquire the ReadAccess lock. I used `std::shared_timed_mutex` instead of `std::shared_mutex` and set a minimum block time of 10ms.

I update the git repo with the working solution if anyone is interested.

eriksl
Posts: 199
Joined: Thu Dec 14, 2023 3:23 pm
Location: Netherlands

Re: Unexpected behavior of std::shared_lock<std::shared_mutex>

Postby eriksl » Thu Sep 04, 2025 11:02 am

But the low-down, is it an "undocumented feature" in your code, or should the Espressif git repository be fixed?

Who is online

Users browsing this forum: Baidu [Spider], Google [Bot] and 1 guest