Рассмотрим реализацию boost::mutex (последняя версия)
bool timed_lock(::boost::system_time const& wait_until)
{
(1) if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit))
{
return true;
}
long old_count=active_count;
(2) for(;;)
{
long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value);
long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
if(current==old_count)
{
break;
}
old_count=current;
}
if(old_count&lock_flag_value)
{
bool lock_acquired=false;
void* const sem=get_event();
do
{
(3) if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until))!=0)
{
BOOST_INTERLOCKED_DECREMENT(&active_count);
return false;
}
old_count&=~lock_flag_value;
old_count|=event_set_flag_value;
for(;;)
{
long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value;
long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
if(current==old_count)
{
break;
}
old_count=current;
}
lock_acquired=!(old_count&lock_flag_value);
}
while(!lock_acquired);
}
return true;
}
void unlock()
{
long const offset=lock_flag_value;
(4) long const old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,lock_flag_value);
if(!(old_count&event_set_flag_value) && (old_count>offset))
{
(5) if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit))
{
win32::SetEvent(get_event());
}
}
}
рассмотрим такую ситуацию
Имеем три потока с приоритетами Low, Medium, High
в начальном состоянии поток Low захватил mutex в точке 1 потому что он первый,
далее начинает работать стартует поток Medium система передает ему управление так как он имеет более высокий приоритет
потом начинает работать поток High и пытается захватить mutex, так как mutex уже захвачен доходит до точки 3 и ждет
так как поток High ждет, управление передается потоку Medium и пока он не отработает не произойдет инверсии приоритета для
потока Low и поток High не получит управления.
Вот такая дыра обнаружилась