Чтение онлайн

на главную - закладки

Жанры

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:

 // с идентификатором нити-влядельца.

 // Если это не так, скорее всего мы имеем дело с ошибкой

 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

К

сожалению, пришлось даже переопределить CScopeLock lock(cs), причем мы жестко привязались к имени переменной. Не говоря уж о том, что у нас наверняка получился конфликт имен, все-таки Lock довольно популярное название для метода. Такой код не будет собираться, например, с популярнейшей библиотекой ATL. Тут есть два способа. Переименовать наши методы Lock и TryLock во что-нибудь более уникальное либо переименовать Lock в ATL:

Поделиться:
Популярные книги

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Измена. Отбор для предателя

Лаврова Алиса
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Отбор для предателя

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Шаг в бездну

Муравьёв Константин Николаевич
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Шаг в бездну

Часовая битва

Щерба Наталья Васильевна
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Часовая битва

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Хроники странного королевства. Вторжение. (Дилогия)

Панкеева Оксана Петровна
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)

Часовой ключ

Щерба Наталья Васильевна
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Часовой ключ

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9