Когда фильтр исключений возвращает EXCEPTION_EXECUTE_HANDLER, системе при ходится проводить глобальную раскрутку Она приводит к продолжению обработки всех незавершенных блоков try-finally, выполнение которых началось вслед за блоком try-except, обрабатывающим данное исключение. Блок-схема на рис. 24-2 поясняет, как система осуществляет глобальную раскрутку Посматривайте на эту схему, когда бу дете читать мои пояснения к следующему примеру
Рис. 24-2. Так система проводит глобальную раскрутку
void FuncOSTimpy1()
{
// 1 Что-то делаем здесь
...
__try
{
// 2 Вызываем другую функцию
FuncORen1();
// этот код никогда не выполняется
}
__except (/* 6 Проверяем фильтр исключений */ EXCEPTION_EXECUTE,HANDLER)
{
// 8 После раскрутки выполняется атот обработчик
MessageBox(....);
}
// 9 Исключение обработано - продолжаем выполнение ...
}
void FuncORen1()
{
DWORD dwTemp = 0;
// 3. Что-то делаем здесь
...
__try
{
// 4. Запрашиваем разрешение на доступ к защищенным данным
WaitForSingleObject(g_nSem, INFINITE);
// 5. Изменяем данные, и здесь генерируется исключение
g_dwProtectedData = 5 / dwTemp;
}
__finally
{
// 7. Происходит глобальная раскрутка, так как
// фильтр возвращает FXCFPTTON_EXECUTE_HANDLER
// Даем и другим попользоваться защищенными данными
ReleaseSemaphore(g_hScm, 1, NULL);
}
// сюда мы никогда не попадем
...
}
FuncOStimpyl и FuncORen1 иллюстрируют самые запутанные аспекты структурной обработки исключений. Номера в начале комментариев показывают порядок выпол нения, в котором сходу не разберешься, но возьмемся за руки и пойдем вместе.
FuncOStimpy1 начинает выполнение со входа в свой блок try и вызова FuncORen1. Последняя тоже начинает со входа в свой блок try и ждет освобождения семафора. Завладев им, она пытается изменить значение глобальной переменной g_dwProtected Data. Деление на нуль возбуждает исключение. Система, перехватив управление, ищет блок try, которому соответствует блок except. Поскольку блоку try функции FuncORenl соответствует 6лок finally, система продолжает поиск и находит блок try в FuncOStim py1, которому как раз и соответствует блок except.