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: Rodionov Andrew <camelot58@…> 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 viboes, 9 years ago

Component: Nonethread
Owner: set to viboes
Status: newassigned

comment:2 by viboes, 9 years ago

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?

comment:3 by viboes, 9 years ago

Milestone: To Be DeterminedBoost 1.57.0

comment:4 by viboes, 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:5 by viboes, 8 years ago

Any new on this issue?

comment:7 by viboes, 8 years ago

Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.