Программирование на Visual C++. Архив рассылки
Шрифт:
ATLASSERT(sem);
if (!(ret = (HANDLE)::InterlockedCompareExchangePointer(
&pcs->LockSemaphore, sem, NULL))) ret = sem;
else ::CloseHandle(sem); // Кто-то успел раньше
}
return ret;
}
// Ждем, пока критическая секция не освободится либо время ожидания
// будет превышено
static inline VOID _WaitForCriticalSectionDbg(LPCRITICAL_SECTION_DBG pcs, int nLine, LPCSTR azFile) {
HANDLE sem = _CriticalSectionGetEvent(pcs);
DWORD dwWait;
do {
dwWait = ::WaitForSingleObject(sem, DEADLOCK_TIMEOUT);
if (WAIT_TIMEOUT == dwWait) {
ATLTRACE("Critical section timeout (%u msec):"
" tid 0x%04X owner tid 0x%04X\n"
"Owner lock from %hs line %u, waiter %hs line %u\n",
DEADLOCK_TIMEOUT, ::GetCurrentThreadId, pcs->OwningThread,
pcs->m_azFile, pcs->m_nLine, azFile, nLine);
}
} while(WAIT_TIMEOUT == dwWait);
ATLASSERT(WAIT_OBJECT_0 == dwWait);
}
//
Выставляем событие в активное состояние
static inline VOID _UnWaitCriticalSectionDbg(LPCRITICAL_SECTION pcs) {
HANDLE sem = _CriticalSectionGetEvent(pcs);
BOOL b = ::SetEvent(sem);
ATLASSERT(b);
}
// Инициализируем критическую секцию.
inline VOID InitializeCriticalSectionDbg(LPCRITICAL_SECTION_DBG pcs) {
// Пусть система заполнит свои поля
InitializeCriticalSection(pcs);
// Заполняем наши поля
pcs->m_nLine = 0;
pcs->m_azFile = NULL;
}
// Освобождаем ресурсы, занимаемые критической секцией
inline VOID DeleteCriticalSectionDbg(LPCRITICAL_SECTION_DBG pcs) {
// Проверяем, чтобы не было удалений "захваченных" критических секций
ATLASSERT(0 == pcs->m_nLine && NULL == pcs->m_azFile);
// Остальное доделает система
DeleteCriticalSection(pcs);
}
// Заполучем критическую секцию в свое пользование
inline VOID EnterCriticalSectionDbg(LPCRITICAL_SECTION_DBG pcs, int nLine, LPSTR azFile) {
if (::InterlockedIncrement(&pcs->LockCount)) {
// LockCount
стал больше нуля.
// Проверяем идентификатор нити
if (pcs->OwningThread == (HANDLE)::GetCurrentThreadId) {
// Нить та же самая. Критическая секция наша.
// Никаких дополнительных действий не производим.
// Это не совсем верно, так как возможно, что непарный
// вызов ::LeaveCriticalSection был на n-ном заходе,
// и это прийдется отлавливать вручную, но реализация
// стека для __LINE__ и __FILE__ сделает нашу систему
// более громоздкой. Если это действительно необходимо,
// Вы всегда можете сделать это самостоятельно
pcs->RecursionCount++;
return;
}
// Критическая секция занята другой нитью.
// Придется подождать
_WaitForCriticalSectionDbg(pcs, nLine, azFile);
}
// Либо критическая секция была "свободна",
// либо мы дождались. Сохраняем идентификатор текущей нити.
pcs->OwningThread = (HANDLE)::GetCurrentThreadId;
pcs->RecursionCount = 1;
pcs->m_nLine = nLine;
pcs->m_azFile = azFile;
}
// Заполучаем критическую секцию если она никем не занята
inline BOOL TryEnterCriticalSectionDbg(LPCRITICAL_SECTION_DBG pcs, int nLine, LPSTR azFile) {
if (-1L == ::InterlockedCompareExchange(&pcs->LockCount, 0, -1)) {
// Это первое обращение к критической секции
pcs->OwningThread = (HANDLE)::GetCurrentThreadId;
pcs->RecursionCount = 1;
pcs->m_nLine = nLine;
pcs->m_azFile = azFile;
} else if (pcs->OwningThread == (HANDLE)::GetCurrentThreadId) {
// Это не первое обращение, но из той же нити
::InterlockedIncrement(&pcs->LockCount);
pcs->RecursionCount++;
} else return FALSE; // Критическая секция занята другой нитью
return TRUE;
}
// Освобождаем критическую секцию
inline VOID LeaveCriticalSectionDbg(LPCRITICAL_SECTION_DBG pcs) {
// Проверяем, чтобы идентификатор текущей нити совпадал
Поделиться:
Популярные книги
Черный маг императора 3
3. Черный маг императора
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Повелитель механического легиона. Том VIII
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Пипец Котенку! 3
3. РОС: Пипец Котенку!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Разбуди меня
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Боги, пиво и дурак. Том 6
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Болотник 2
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Ты всё ещё моя
4. Под запретом
Любовные романы:
современные любовные романы
7.00
рейтинг книги
S-T-I-K-S. Пройти через туман
Вселенная S-T-I-K-S
Фантастика:
боевая фантастика
7.00
рейтинг книги
Имя нам Легион. Том 4
4. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Сводный гад
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Я князь. Книга XVIII
18. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Королевская Академия Магии. Неестественный Отбор
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Последняя Арена 6
6. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Жребий некроманта. Надежда рода
1. Жребий некроманта
Фантастика:
фэнтези
попаданцы
6.50