id summary reporter owner description type status milestone component version severity resolution keywords cc 5516 Upgrade lock is not acquired when previous upgrade lock releases if another read lock is present fred@… viboes "Thread 1 acquires a read lock on a shared mutex[[BR]] Thread 2 acquires an upgrade lock on the shared mutex[[BR]] Thread 3 tries to acquire an upgrade lock on the shared mutex, waits for it[[BR]] Thread 2 releases the lock At this point, I would expect thread 3 to acquire the lock, but it does not do it until thread 1 releases its read lock. This seems to be caused by the ""shared_mutex ::unlock_upgrade()"" method in thread/pthread/shared_mutex.hpp, that only calls ""release_waiters()"" if it is the last reader, ignoring that another upgrade lock might be waiting to take the lock. I suppose it could be fixed by maintaining a count of the number of threads waiting for an upgrade lock, and to signal the shared condition if this is non-zero. Here is an example program: {{{ #include #include class Test { public: void m1() { std::cout << ""m1 - Trying to take an shared lock"" << std::endl; boost::shared_lock lock(_mutex); std::cout << ""m1 - Took a shared lock"" << std::endl; sleep(5); std::cout << ""m1 - Released the lock"" << std::endl; } void m2() { sleep(1); std::cout << ""m2 - Trying to take an upgradable lock"" << std::endl; boost::upgrade_lock lock(_mutex); std::cout << ""m2 - Took an upgradable lock"" << std::endl; sleep(1); std::cout << ""m2 - Released an upgradable lock"" << std::endl; } void m3() { sleep(2); std::cout << ""m3 - Trying to take an upgradable lock"" << std::endl; boost::upgrade_lock lock(_mutex); std::cout << ""m3 - Took an upgradable lock"" << std::endl; std::cout << ""m3 - Releasing locks"" << std::endl; } void run() { boost::thread t1(&Test::m1, this); boost::thread t2(&Test::m2, this); m3(); t1.join(); t2.join(); } private: boost::shared_mutex _mutex; }; int main() { Test test; test.run(); return 0; } }}} Results: {{{ m1 - Trying to take an shared lock m1 - Took a shared lock m2 - Trying to take an upgradable lock m2 - Took an upgradable lock m3 - Trying to take an upgradable lock m2 - Released an upgradable lock m1 - Released the lock m3 - Took an upgradable lock m3 - Releasing locks }}} Expected: {{{ m1 - Trying to take an shared lock m1 - Took a shared lock m2 - Trying to take an upgradable lock m2 - Took an upgradable lock m3 - Trying to take an upgradable lock m2 - Released an upgradable lock m3 - Took an upgradable lock m3 - Releasing locks m1 - Released the lock }}} Tested in Boost 1.42, visually checked that Trunk would have the same behaviour. " Patches closed Boost 1.50.0 thread Boost 1.42.0 Problem fixed viboes