Opened 9 years ago
Closed 8 years ago
#9569 closed Bugs (fixed)
[windows] Upgrade lock is not acquired when previous upgrade lock releases if another read lock is present
| Reported by: | Owned by: | viboes | |
|---|---|---|---|
| Milestone: | Boost 1.57.0 | Component: | thread |
| Version: | Boost 1.55.0 | Severity: | Problem |
| Keywords: | shared_mutex windows | Cc: |
Description
The problem is described here https://svn.boost.org/trac/boost/ticket/5516. Example and result are the same. The only difference is that I use <boost/thread/win32/shared_mutex.hpp> instead of <boost/thread/pthread/shared_mutex.hpp>.
I tried to compile with BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN flag and everything goes right. So the problem is in function unlock_upgrade() in <boost/thread/win32/shared_mutex.hpp>.
My platform: Windows 7 x64, MS VS 2012.
Change History (7)
comment:1 by , 9 years ago
| Component: | None → thread |
|---|---|
| Owner: | set to |
| Status: | new → assigned |
comment:2 by , 9 years ago
comment:3 by , 9 years ago
| Milestone: | To Be Determined → Boost 1.57.0 |
|---|
comment:4 by , 8 years ago
| Summary: | Upgrade lock is not acquired when previous upgrade lock releases if another read lock is present → [windows] Upgrade lock is not acquired when previous upgrade lock releases if another read lock is present |
|---|
comment:6 by , 8 years ago
comment:7 by , 8 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
Note:
See TracTickets
for help on using tickets.

Hi,
Please could you try adding
void release_shared_waiters(state_data old_state) { if(old_state.shared_waiting || old_state.exclusive_waiting) { BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0); } }and changing the implementation to
void unlock_upgrade() { state_data old_state=state; for(;;) { state_data new_state=old_state; new_state.upgrade=false; bool const last_reader=!--new_state.shared_count; if(last_reader) { if(new_state.exclusive_waiting) { --new_state.exclusive_waiting; new_state.exclusive_waiting_blocked=false; } new_state.shared_waiting=0; } state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); if(current_state==old_state) { if(last_reader) { release_waiters(old_state); } else { release_shared_waiters(old_state); } // #7720 //else { // release_waiters(old_state); //} break; } old_state=current_state; } }Please could you also try the test in #7720?