Нужно освободить ресурсы при выгрузке dll. В том числе завершить поток, который был создан в dll. Это нужно сделать в DllMain().
Поток может зависнуть на одной из функций секунд на 10. Нужно сначала завершить поток, а дальше освобождать память, закрывать хэндлы.
Пробовал дождаться завершения операции потоком, проверяя общую переменную. Синхронизация потоков через mutex. Завершение операции не наступает. В документации предупреждали, что в DllMain() нельзя заниматься синхронизацией потоков.
Пробовал завершить поток с помощью TerminateThread(). Завершается успешно, но после этого зависание на delete obj.
Здравствуйте, nekoriu, Вы писали:
N>Здравствуйте.
N>Нужно освободить ресурсы при выгрузке dll. В том числе завершить поток, который был создан в dll. Это нужно сделать в DllMain(). N>Поток может зависнуть на одной из функций секунд на 10. Нужно сначала завершить поток, а дальше освобождать память, закрывать хэндлы.
N>Пробовал дождаться завершения операции потоком, проверяя общую переменную. Синхронизация потоков через mutex. Завершение операции не наступает. В документации предупреждали, что в DllMain() нельзя заниматься синхронизацией потоков.
N>Пробовал завершить поток с помощью TerminateThread(). Завершается успешно, но после этого зависание на delete obj.
N>Есть идеи?
А кто создает поток в DLL? Код потока свой? Может ему передать какой-нить event, для синхронизации с основным приложением на предмет давай завершайся?
N>Пробовал завершить поток с помощью TerminateThread(). Завершается успешно, но после этого зависание на delete obj. N>Есть идеи?
возможны разные хаки, но правильнее всего — сделать экспортную функцию Finalize которую дергать до FreeLibrary
Как много веселых ребят, и все делают велосипед...
C>А кто создает поток в DLL? Код потока свой? Может ему передать какой-нить event, для синхронизации с основным приложением на предмет давай завершайся?
Поток создаю я. В планах попробовать из потока dll сообщить пользовательскому потоку "я завершился" с помощью event. Поток из dll может зависнуть секунд на 10 на функции из wininet.
O>возможны разные хаки, но правильнее всего — сделать экспортную функцию Finalize которую дергать до FreeLibrary
Заказчик хочет, чтобы Finalize, вызывалась автоматически при вызове FreeLibrary.
Здравствуйте, nekoriu, Вы писали:
C>>А кто создает поток в DLL? Код потока свой? Может ему передать какой-нить event, для синхронизации с основным приложением на предмет давай завершайся?
N>Поток создаю я. В планах попробовать из потока dll сообщить пользовательскому потоку "я завершился" с помощью event. Поток из dll может зависнуть секунд на 10 на функции из wininet.
Что то я не понял!?! Поток в DLL, который может долго завершаться, создается в самой DLL? И код создания потока в самой DLL, то же Ваш?
Можно его менять?
Если весь код Ваш, то вариантов только два
1) Поток, в котором выполняется DLLMain и поток который создается внутри ДЛЛ должны как то синхронизироваться. Т.е. поток из коорого выполняется DLLMain, должен как-то сказать этому фоновому потоку давай завершайся. И соответственно этот фоновый поток должен периодически проверять какой-нить примитив синхронизации вроде эвента, а не пора ли на выход...
2) Ну как правильно сказал ononim должна быть экспортная функция Finalize, чтобы вызывающий код из самого внешнего exe-процесса четко понимал, что завершение этого Finalize может занять время. Что делать в вызывающем коде с таким ожиданием другой разговор (путь хоть таймер с обратным отчетом, и кнопкой "Не ждать — завершить сейчас".
Тут как бы в таком случае всё очевидно и детерминировано для вызывающего кода.
В DLLMain все те же проблемы, все те же ожидания завершения и.т.л. Только а) ничего совсем не очевидно, что там какой-то фоновый поток еще в DLL завершаться будет б) никакого пространства для творчества — прототип DllMain определен, и все (вызывающий код) ожидают вполне определенное поведение.
А вообще это называется *авно-дизайн!!!
Кто что там нараспределял, позапускал (хендлы, память), тот за то и отвечает. А так все эти левые фоновые потоки, которые создаются в DLL, какие-то невидимки. Зомби просто... Чего то там делают, информации о них наружу почти что ноль, но взаимодействовать с ними надо.. Надо как-то иначе проектировать такую ситуацию.
C>Что то я не понял!?! Поток в DLL, который может долго завершаться, создается в самой DLL? И код создания потока в самой DLL, то же Ваш? C>Можно его менять?
C>Если весь код Ваш, то вариантов только два C>1) Поток, в котором выполняется DLLMain и поток который создается внутри ДЛЛ должны как то синхронизироваться. Т.е. поток из коорого выполняется DLLMain, должен как-то сказать этому фоновому потоку давай завершайся. И соответственно этот фоновый поток должен периодически проверять какой-нить примитив синхронизации вроде эвента, а не пора ли на выход...
C>2) Ну как правильно сказал ononim должна быть экспортная функция Finalize, чтобы вызывающий код из самого внешнего exe-процесса четко понимал, что завершение этого Finalize может занять время. Что делать в вызывающем коде с таким ожиданием другой разговор (путь хоть таймер с обратным отчетом, и кнопкой "Не ждать — завершить сейчас".
C>Тут как бы в таком случае всё очевидно и детерминировано для вызывающего кода. C>В DLLMain все те же проблемы, все те же ожидания завершения и.т.л. Только а) ничего совсем не очевидно, что там какой-то фоновый поток еще в DLL завершаться будет б) никакого пространства для творчества — прототип DllMain определен, и все (вызывающий код) ожидают вполне определенное поведение.
C>А вообще это называется *авно-дизайн!!! C>Кто что там нараспределял, позапускал (хендлы, память), тот за то и отвечает. А так все эти левые фоновые потоки, которые создаются в DLL, какие-то невидимки. Зомби просто... Чего то там делают, информации о них наружу почти что ноль, но взаимодействовать с ними надо.. Надо как-то иначе проектировать такую ситуацию.
Поток, который может долго завершаться, создается в Dll. Сам его создаю, код потока мой.
C>>А вообще это называется *авно-дизайн!!! C>>Кто что там нараспределял, позапускал (хендлы, память), тот за то и отвечает. А так все эти левые фоновые потоки, которые создаются в DLL, какие-то невидимки. Зомби просто... Чего то там делают, информации о них наружу почти что ноль, но взаимодействовать с ними надо.. Надо как-то иначе проектировать такую ситуацию. N>Поток, который может долго завершаться, создается в Dll. Сам его создаю, код потока мой.
Ну тогда соответственно только синхрониться с фоновым потоком, из основного потока в котором работает DllMain
Согласно вот этому, Вами же и озвученному
Нужно освободить ресурсы при выгрузке dll. В том числе завершить поток, который был создан в dll. Это нужно сделать в DllMain().
Поток может зависнуть на одной из функций секунд на 10. Нужно сначала завершить поток, а дальше освобождать память, закрывать хэндлы.
Фигня какя-то в дизайне? Почему надо сначала завершить фоновый поток, а только потом освобождать ресурсы (память, хендлы)?
Кто эти ресурсы распределял? Поток в котором работает DllMain, или этот фоновый поток?
Если фоновый поток распределял, то пусть он же и освобождает. Если, распределял поток ДллМайн, то зачем ему ждать завершения фонового потока?
Что то тут не до в консерватории...
По уму кто распределял, тот поток и должен освобождать. Распределителю всегда лучше знать, что он и как распределил, и когда можно это освободить.
Иначе нужно как-то синхронизироваться между потоками. Ибо первый основной поток распределил ресурсы, запустил фоновый поток, который эти ресурсы пользует, а потом основной поток удалил ресурсы и вернул управление…
А откуда фоновому потоку узнать, что ресурсы ему переданные из основного потока в момент Икс протухли и освободились? А фоновый поток ресурсы
эти всё еще использует?
Тут или синхронизация должна быть между потоками. Или что нить вроде shared_ptr, который сам все удалит, когда счетчик использования ресурсов обнулится.
А вообще нужны подробности постановки задачи. Вроде как аккурат попахивает неправильным дизайном, неверным проектированием.
O>>возможны разные хаки, но правильнее всего — сделать экспортную функцию Finalize которую дергать до FreeLibrary N>Заказчик хочет, чтобы Finalize, вызывалась автоматически при вызове FreeLibrary.
А как насчет варианта, что при запуске потока длл будет делать LoadLibrary сама на себя, а поток будет гулять сам по себе, но выходить через FreeLibraryAndExitThread.
Получится что FreeLibrary не всегда будет приводить к реальной выгрузке длл.. А нужна ли эта реальная выгрузка?
Как много веселых ребят, и все делают велосипед...
Здравствуйте, nekoriu, Вы писали:
N>Здравствуйте.
N>Нужно освободить ресурсы при выгрузке dll. В том числе завершить поток, который был создан в dll. Это нужно сделать в DllMain(). N>Поток может зависнуть на одной из функций секунд на 10. Нужно сначала завершить поток, а дальше освобождать память, закрывать хэндлы.
FreeLibraryAndExitThread не подойдет? Или что-то повесить в DLL_PROCESS_DETACH
Всем спасибо. Пока этой темой не занимаюсь. Остановился на явном вызове Finalize. У меня были проблемы при потоковой синхронизации в DllMain, при использовании wininet в DllMain, как и обещали в документации.