Есть Не кая библиотека, которая выгружается из процесса в произвольное время. Вопрос в следующем В длл создаются потоки, после того как получаю DLL_PROCESS_DETACH, нужно дождатся завершения этих потоков. WaitFor**** MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx Получается WaitFor**** использовать нельзя, вопрос тогда синхронизировать? Циклы со слипами очень плохая идея... П.С. Операции new delete получается тоже нельзя использовать.
shchetinin Циклы со слипами — это то же самое, что вызов ожидания на потоке, т.к. потоки не завершатся, пока DllMain не вернёт управление, потому что сами потоки тоже должны сериализовано пройти через DllMain. А с ожиданием внутри DllMain она не вернёт управление, пока потоки не завершатся. DLL_PROCESS_DETACH может произойти в трёх случаях: 1) Вызван ExitProcess. В этом случае ожидать уже некого, т.к. все потоки кроме текущего уже завершены. 2) Ошибка инициализации процесса. В этом случае ожидать ещё некого, т.к. все потоки кроме текущего ещё не стартовали (и не будут стартовать). 3) Счётчик загрузок dll достиг нуля. Сделать так, чтобы этого не происходило, пока свои потоки не завершатся, очень просто: каждый поток должен в начале своего исполнения сделать LoadLibrary, а на выходе делать FreeLibraryAndExitThread.
l_inc 1. Если какой либо поток не покинул загрузчик, то поток вызвавший в это время ExitProcess() будет ждать. Если тред не покинувший загрузчик, например в дллмейн будет ждать завершение треда вызывающего ExitProcess(), то возникнет деадлок. Всякий вызов нтлдр-колбеков синхронизируется через кс LdrpLoaderLock. 2. При ошибках в лодере генерится рейс. 3. Нотификация не зависит от числа ссылок. В частном случае при выгрузке модуля будет нотификация если счётчик ссылок на модуль уменьшился до предельного значения. shchetinin Ваш вопрос не конкретный, нельзя однозначно на него ответить. Если в модуле ваш код, модуль выгружается а в условии ваш выгружаемый код должен работать(ждать друние треды), то это логическая ошибка. Такого не может быть. Код либо есть, либо его нет и он не исполняется. Иначе сформулируйте задачу конкретно. Верная формулировка вопроса это почти готовый ответ.
thuwiaki 1. Я вообще-то то же самое написал в первом параграфе. 2. Какой нафиг рейс? Этот пункт вообще не понял. 3. И что? Какое это отношение имеет к тому, что я сказал?
l_inc 1. Вы написали про отсутствие потоков, кроме текущего. В данном случае вопрос не имеет смысла. Если потоки есть, то вашу попытку ответа нельзя считать ответом, ибо она не включает в себя многопоточность. Студентик эту тему пропустил 2. Рейс. Тот который генерит фолт. Через рейссепшен. 3. Ваш текст не имеет смысла.
thuwiaki 1. В первом параграфе поста, а не в пункте 1). Потоков быть не может. Т.к. нотификация DLL_PROCESS_DETACH согласно MSDN приходит только если все остальные потоки уже завершены. Студентик в отличие от "илито" умеет читать не только (диз-)ассемблерные листинги. Чужие посты, например. 2. Я Ваши попытки транслитерации не понимаю. Ошибка инициализации процесса в случае, если приходит нотификация DLL_PROCESS_DETACH, возникает, например, в том случае, если какая-то dll из своей DllMain вернула ошибку. На этот момент существует только первичный поток, исполняющий код загрузчика (+ DllMain dll'ок, TLS-callback'и и, может, что-то ещё). 3. Могу то же самое сказать про Ваш текст по этому пункту.
l_inc Я не читал мсдн, но могу вас заверить что эта нотифи доставляется при выгрузке модуля, вне зависимости от других тредов(если конечно они не залочили лодер). 2. Генерится рейс. Смотреть дизасм или сорц.
thuwiaki 1. Я ж и говорю, что умею читать чуть больше, чем "дизасм или сорц". А вообще я для того MSDN и процитировал, чтобы Вам слишком много читать не пришлось. В общем, Вы хотите сказать, что, если один из, скажем, десяти потоков вызовет ExitProcess, то DLL_PROCESS_DETACH может доставляться во все dll-ки ещё до того, как остальные девять потоков завершились? 2. Я под Вашим "рейс" могу только race сondition представить. К сожалению смысла для меня это не имеет.
Что то я провмыкал ... Это проблема будет только при ожидании завершении потока. Из за нотификации DLL_THREAD_DETACH. Так делаем call DisableThreadLibraryCalls(hModule)
l_inc 1. Ну ты и твердолобый. Не имеет эта нотифи никакого отношения к завершению процесса. Она доставляется при выгрузке модуля. 2. Рейс это то, что генерится через NtRaiseException. В мсдн посмотрите, вы же умеете читать чуть больше, чем "дизасм или сорц".
thuwiaki Это бред. ExitProcess => выгрузка модуля => вызов DllMain с причиной DLL_PROCESS_DETACH. Так вот когда DllMain с причиной DLL_PROCESS_DETACH вызывается, как следствие ExitProcess, все ещё живые на момент вызова ExitProcess потоки, кроме того, в контексте которого исполняется DllMain, принудительно уничтожаются. Ах вот оно что! Транслитерация-то неверная. Это читается, как рейз. К сожалению забыл заказать версию MSDN в кривом транслите. А так бы прочитал, конечно.
thuwiaki l_inc В том то и проблема что происходит только выгрузка модуля, а не завершение процесса. и архитерктура не моя ... так что такая вот ажа вышла... ну что то я провмыкал ...