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

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

Жанры

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

Jenter Алекс

Шрифт:

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
рейтинг книги
Черный маг императора 3

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

Пипец Котенку! 3

Майерс Александр
3. РОС: Пипец Котенку!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Пипец Котенку! 3

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Боги, пиво и дурак. Том 6

Горина Юлия Николаевна
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 6

Болотник 2

Панченко Андрей Алексеевич
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Болотник 2

Ты всё ещё моя

Тодорова Елена
4. Под запретом
Любовные романы:
современные любовные романы
7.00
рейтинг книги
Ты всё ещё моя

S-T-I-K-S. Пройти через туман

Елисеев Алексей Станиславович
Вселенная S-T-I-K-S
Фантастика:
боевая фантастика
7.00
рейтинг книги
S-T-I-K-S. Пройти через туман

Имя нам Легион. Том 4

Дорничев Дмитрий
4. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 4

Сводный гад

Рам Янка
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Сводный гад

Я князь. Книга XVIII

Дрейк Сириус
18. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я князь. Книга XVIII

Королевская Академия Магии. Неестественный Отбор

Самсонова Наталья
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Королевская Академия Магии. Неестественный Отбор

Последняя Арена 6

Греков Сергей
6. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 6

Жребий некроманта. Надежда рода

Решетов Евгений Валерьевич
1. Жребий некроманта
Фантастика:
фэнтези
попаданцы
6.50
рейтинг книги
Жребий некроманта. Надежда рода