К нашему большому удивлению, мы недавно нашли это . С SP1 для Windows 2003 Microsoft изменила способ поведения критических секций. Ранее потоки, желающие получить к ним доступ, обслуживались в порядке FIFO. Прямо сейчас они подаются в чистом «случайном» порядке.
В нашем случае у нас было что-то вроде этого:
// I now it's kind of ugly design but works
void Class:RunInThread()
{
while(m_Running)
{
EnterCriticalSection(&m_CS);
DoSomeStuffWithList();
LeaveCriticalSection(&m_CS);
}
}
void Class::AddToList()
{
EnterCriticalSection(&m_CS);
AddSomeStuffToList();
LeaveCriticalSection(&m_CS);
}
Таким образом, с новой реализацией критической секции в 2003 году SP2 AddToList может умереть от голода, поскольку нет никаких гарантий, что он будет пробужден.
Этот пример несколько экстремален, но, с другой стороны, у меня есть миллионов строк кода, которые были написаны с предположением, что доступ к критическим секциям сериализован.
Есть ли способ отключить этот новый критический раздел?
РЕДАКТИРОВАТЬ: Поскольку возврат старой версии невозможен, я думаю просто выполнить глобальный поиск и замену, чтобы изменить {Enter, Leaver} CriticalSection на что-то вроде My {Enter, Leave} CriticalSection. У вас есть идеи, как это должно быть реализовано, чтобы оно точно походило на версию до SP2?