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.