DllMain DLL_PROCESS_DETACH

Тема в разделе "WASM.WIN32", создана пользователем shchetinin, 6 окт 2011.

  1. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Есть Не кая библиотека, которая выгружается из процесса в произвольное время. Вопрос в следующем
    В длл создаются потоки, после того как получаю DLL_PROCESS_DETACH, нужно дождатся завершения этих потоков. WaitFor****

    MSDN
    http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx
    Получается WaitFor**** использовать нельзя, вопрос тогда синхронизировать?
    Циклы со слипами очень плохая идея...

    П.С.
    Операции new delete получается тоже нельзя использовать.
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    shchetinin
    Циклы со слипами — это то же самое, что вызов ожидания на потоке, т.к. потоки не завершатся, пока DllMain не вернёт управление, потому что сами потоки тоже должны сериализовано пройти через DllMain. А с ожиданием внутри DllMain она не вернёт управление, пока потоки не завершатся.

    DLL_PROCESS_DETACH может произойти в трёх случаях:
    1) Вызван ExitProcess. В этом случае ожидать уже некого, т.к. все потоки кроме текущего уже завершены.
    2) Ошибка инициализации процесса. В этом случае ожидать ещё некого, т.к. все потоки кроме текущего ещё не стартовали (и не будут стартовать).
    3) Счётчик загрузок dll достиг нуля. Сделать так, чтобы этого не происходило, пока свои потоки не завершатся, очень просто: каждый поток должен в начале своего исполнения сделать LoadLibrary, а на выходе делать FreeLibraryAndExitThread.
     
  3. thuwiaki

    thuwiaki New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2011
    Сообщения:
    25
    l_inc
    1. Если какой либо поток не покинул загрузчик, то поток вызвавший в это время ExitProcess() будет ждать. Если тред не покинувший загрузчик, например в дллмейн будет ждать завершение треда вызывающего ExitProcess(), то возникнет деадлок. Всякий вызов нтлдр-колбеков синхронизируется через кс LdrpLoaderLock.
    2. При ошибках в лодере генерится рейс.
    3. Нотификация не зависит от числа ссылок. В частном случае при выгрузке модуля будет нотификация если счётчик ссылок на модуль уменьшился до предельного значения.

    shchetinin
    Ваш вопрос не конкретный, нельзя однозначно на него ответить. Если в модуле ваш код, модуль выгружается а в условии ваш выгружаемый код должен работать(ждать друние треды), то это логическая ошибка. Такого не может быть. Код либо есть, либо его нет и он не исполняется. Иначе сформулируйте задачу конкретно. Верная формулировка вопроса это почти готовый ответ.
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    thuwiaki
    1. Я вообще-то то же самое написал в первом параграфе.
    2. Какой нафиг рейс? Этот пункт вообще не понял.
    3. И что? Какое это отношение имеет к тому, что я сказал?
     
  5. thuwiaki

    thuwiaki New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2011
    Сообщения:
    25
    l_inc
    1. Вы написали про отсутствие потоков, кроме текущего. В данном случае вопрос не имеет смысла. Если потоки есть, то вашу попытку ответа нельзя считать ответом, ибо она не включает в себя многопоточность. Студентик эту тему пропустил :lol:

    2. Рейс. Тот который генерит фолт. Через рейссепшен.

    3. Ваш текст не имеет смысла.
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    thuwiaki
    1. В первом параграфе поста, а не в пункте 1).
    Потоков быть не может. Т.к. нотификация DLL_PROCESS_DETACH согласно MSDN приходит только если все остальные потоки уже завершены.
    Студентик в отличие от "илито" умеет читать не только (диз-)ассемблерные листинги. :derisive: Чужие посты, например.

    2. Я Ваши попытки транслитерации не понимаю. Ошибка инициализации процесса в случае, если приходит нотификация DLL_PROCESS_DETACH, возникает, например, в том случае, если какая-то dll из своей DllMain вернула ошибку. На этот момент существует только первичный поток, исполняющий код загрузчика (+ DllMain dll'ок, TLS-callback'и и, может, что-то ещё).

    3. Могу то же самое сказать про Ваш текст по этому пункту.
     
  7. thuwiaki

    thuwiaki New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2011
    Сообщения:
    25
    l_inc
    Я не читал мсдн, но могу вас заверить что эта нотифи доставляется при выгрузке модуля, вне зависимости от других тредов(если конечно они не залочили лодер).

    2. Генерится рейс. Смотреть дизасм или сорц.
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    thuwiaki
    1.
    Я ж и говорю, что умею читать чуть больше, чем "дизасм или сорц". А вообще я для того MSDN и процитировал, чтобы Вам слишком много читать не пришлось.
    В общем, Вы хотите сказать, что, если один из, скажем, десяти потоков вызовет ExitProcess, то DLL_PROCESS_DETACH может доставляться во все dll-ки ещё до того, как остальные девять потоков завершились?

    2.
    Я под Вашим "рейс" могу только race сondition представить. К сожалению смысла для меня это не имеет.
     
  9. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Что то я провмыкал ... Это проблема будет только при ожидании завершении потока. Из за нотификации DLL_THREAD_DETACH. Так делаем call DisableThreadLibraryCalls(hModule)
     
  10. thuwiaki

    thuwiaki New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2011
    Сообщения:
    25
    l_inc
    1. Ну ты и твердолобый. Не имеет эта нотифи никакого отношения к завершению процесса. Она доставляется при выгрузке модуля.
    2. Рейс это то, что генерится через NtRaiseException. В мсдн посмотрите, вы же умеете читать чуть больше, чем "дизасм или сорц".
     
  11. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    thuwiaki
    Это бред. ExitProcess => выгрузка модуля => вызов DllMain с причиной DLL_PROCESS_DETACH. Так вот когда DllMain с причиной DLL_PROCESS_DETACH вызывается, как следствие ExitProcess, все ещё живые на момент вызова ExitProcess потоки, кроме того, в контексте которого исполняется DllMain, принудительно уничтожаются.
    Ах вот оно что! Транслитерация-то неверная. Это читается, как рейз.
    К сожалению забыл заказать версию MSDN в кривом транслите. А так бы прочитал, конечно.
     
  12. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    thuwiaki
    l_inc
    В том то и проблема что происходит только выгрузка модуля, а не завершение процесса. и архитерктура не моя ... так что такая вот ажа вышла... ну что то я провмыкал ...
     
  13. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    shchetinin
    ОК-ок. :) thuwiaki-то независимо от этого ерунду пишет.