Программирование на Visual C++. Архив рассылки
Шрифт:
// с идентификатором нити-влядельца.
// Если это не так, скорее всего мы имеем дело с ошибкой
ATLASSERT(pcs->OwningThread == (HANDLE)::GetCurrentThreadId);
if (--pcs->RecursionCount) {
// Не последний вызов из этой нити.
// Уменьшаем значение поля LockCount
::InterlockedDecrement(&pcs->LockCount);
} else {
// Последний
вызов. Нужно "разбудить" какую-либо
// из ожидающих ниток, если таковые имеются
ATLASSERT(NULL != pcs->OwningThread);
pcs->OwningThread = NULL;
pcs->m_nLine = 0;
pcs->m_azFile = NULL;
if (::InterlockedDecrement(&pcs->LockCount) >= 0) {
// Имеется, как минимум, одна ожидающая нить
_UnWaitCriticalSectionDbg(pcs);
}
}
}
// Удостоверяемся, что ::EnterCriticalSection была вызвана
// до вызова этого метода
inline BOOL CheckCriticalSection(LPCRITICAL_SECTION pcs) {
return pcs->LockCount >= 0
&& pcs->OwningThread == (HANDLE)::GetCurrentThreadId;
}
// Переопределяем все функции для работы с критическими секциями.
// Определение класса CLock должно быть после этих строк
#define InitializeCriticalSection InitializeCriticalSectionDbg
#define InitializeCriticalSectionAndSpinCount(pcs, c) \
InitializeCriticalSectionDbg(pcs)
#define DeleteCriticalSection DeleteCriticalSectionDbg
#define EnterCriticalSection(pcs) EnterCriticalSectionDbg(pcs, __LINE__, __FILE__)
#define TryEnterCriticalSection(pcs) TryEnterCriticalSectionDbg(pcs, __LINE__, __FILE__)
#define LeaveCriticalSection LeaveCriticalSectionDbg
#define CRITICAL_SECTION CRITICAL_SECTION_DBG
#define LPCRITICAL_SECTION LPCRITICAL_SECTION_DBG
#define PCRITICAL_SECTION PCRITICAL_SECTION_DBG
#endif
Приводим наши классы в соответствие
Листинг 17. Классы CLock и CScopeLock, вариант для отладки
class CLock {
friend class CScopeLock;
CRITICAL_SECTION m_CS;
public:
void Init { ::InitializeCriticalSection(&m_CS); }
void Term { ::DeleteCriticalSection(&m_CS); }
#if defined(CS_DEBUG)
BOOL Check { return CheckCriticalSection(&m_CS); }
#endif
#if CS_DEBUG > 1
void Lock(int nLine, LPSTR azFile) {
EnterCriticalSectionDbg(&m_CS, nLine, azFile);
}
BOOL TryLock(int nLine, LPSTR azFile) {
return TryEnterCriticalSectionDbg(&m_CS, nLine, azFile);
}
#else
void Lock {
::EnterCriticalSection(&m_CS);
}
BOOL TryLock {
return ::TryEnterCriticalSection(&m_CS);
}
#endif
void Unlock {
::LeaveCriticalSection(&m_CS);
}
};
class CScopeLock {
LPCRITICAL_SECTION m_pCS;
public:
#if CS_DEBUG > 1
CScopeLock(LPCRITICAL_SECTION pCS, int nLine, LPSTR azFile) : m_pCS(pCS) {
Lock(nLine, azFile);
}
CScopeLock(CLock& lock, int nLine, LPSTR azFile) : m_pCS(&lock.m_CS) {
Lock(nLine, azFile);
}
void Lock(int nLine, LPSTR azFile) {
EnterCriticalSectionDbg(m_pCS, nLine, azFile);
}
#else
CScopeLock(LPCRITICAL_SECTION pCS) : m_pCS(pCS) { Lock; }
CScopeLock(CLock& lock) : m_pCS(&lock.m_CS) { Lock; }
void Lock { ::EnterCriticalSection(m_pCS); }
#endif
~CScopeLock { Unlock; }
void Unlock { ::LeaveCriticalSection(m_pCS); }
};
#if CS_DEBUG > 1
#define Lock Lock(__LINE__, __FILE__)
#define TryLock TryLock(__LINE__, __FILE__)
#define lock(cs) lock(cs, __LINE__, __FILE__)
#endif
К
Поделиться:
Популярные книги
Моя на одну ночь
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Черный Маг Императора 8
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Измена. Отбор для предателя
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга II
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Шаг в бездну
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Часовая битва
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Вечная Война. Книга II
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Часовой ключ
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Инвестиго, из медика в маги
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Кротовский, может, хватит?
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Драконий подарок
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Очешуеть! Я - жена дракона?!
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Идеальный мир для Лекаря 9
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00