Opened 6 years ago
Closed 6 years ago
#12386 closed Bugs (duplicate)
lock_error exception when using try_lock_for() on Windows
| Reported by: | Owned by: | viboes | |
|---|---|---|---|
| Milestone: | To Be Determined | Component: | thread |
| Version: | Boost 1.61.0 | Severity: | Showstopper |
| Keywords: | lock_error | Cc: |
Description
The following program immediately crashes with a lock_error exception on Windows:
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
using namespace boost;
shared_mutex mtx;
void f()
{
while (true)
{
unique_lock<shared_mutex> lock(mtx, defer_lock);
while (!lock.try_lock_for(chrono::milliseconds(1))) {}
}
}
void g()
{
while (true)
{
shared_lock<shared_mutex> lock(mtx, defer_lock);
while (!lock.try_lock_for(chrono::milliseconds(1))) {}
}
}
int main()
{
const int N = 12;
thread* threads[N];
for (int i = 0; i < N; ++i)
threads[i] = new thread(i % 2 ? f : g);
for (int i = 0; i < N; ++i)
threads[i]->join();
return 0;
}
Callstack when the lock_error exception is thrown:
test.exe!boost::throw_exception<boost::lock_error>(const boost::lock_error & e) test.exe!boost::shared_mutex::try_lock_until(const boost::chrono::time_point<boost::chrono::system_clock,boost::chrono::duration<__int64,boost::ratio<1,10000000> > > & tp) test.exe!boost::shared_mutex::try_lock_until<boost::chrono::steady_clock,boost::chrono::duration<__int64,boost::ratio<1,1000000000> > >(const boost::chrono::time_point<boost::chrono::steady_clock,boost::chrono::duration<__int64,boost::ratio<1,1000000000> > > & t) test.exe!boost::shared_mutex::try_lock_for<__int64,boost::ratio<1,1000> >(const boost::chrono::duration<__int64,boost::ratio<1,1000> > & rel_time) test.exe!boost::unique_lock<boost::shared_mutex>::try_lock_for<__int64,boost::ratio<1,1000> >(const boost::chrono::duration<__int64,boost::ratio<1,1000> > & rel_time)
Boost.Thread code that throws the exception, in boost\thread\win32\shared_mutex.hpp:
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
++new_state.exclusive_waiting;
if(!new_state.exclusive_waiting)
{
boost::throw_exception(boost::lock_error()); // <-- HERE
}
new_state.exclusive_waiting_blocked=true;
}
else
{
new_state.exclusive=true;
}
...
Tested with Boost 1.55 and Boost 1.61, both compiled with Visual Studio 2013 in x64 mode, on Windows 10 64-bit.
Change History (4)
comment:1 by , 6 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:2 by , 6 years ago
Can you try to comment
boost::throw_exception(boost::lock_error()); // <-- HERE
and let me know what is the behavior?
comment:3 by , 6 years ago
You can define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN to get the generic implementation. It is slower but IMHO it has less bugs.
comment:4 by , 6 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | assigned → closed |
It seems that this is a duplicate of #11499.

Hi,
I'm really sorry. I have never understood the original implementation.
Any help would be much appreciated.