-
Notifications
You must be signed in to change notification settings - Fork 263
Description
WINRT_NO_MODULE_LOCK can cause application to crash if the Windows system automatically unloads unused DLLs.
See the test code below.
#define WINRT_NO_MODULE_LOCK
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Devices.Bluetooth.h>
#include <thread>
using namespace ::winrt;
using namespace Windows::Foundation;
using namespace Windows::Devices::Bluetooth;
int main()
{
{
std::thread t([]
{
init_apartment();
{
[[maybe_unused]] auto adapter = BluetoothAdapter::GetDefaultAsync().get();
}
// sleep at least 30s so that DLLs will be unloaded when uninit_apartment is called (don't know exactly why)
std::this_thread::sleep_for(std::chrono::seconds(35));
clear_factory_cache();
uninit_apartment();
});
t.join();
}
{
std::thread t([]
{
init_apartment();
{
[[maybe_unused]] auto adapter = BluetoothAdapter::GetDefaultAsync().get();
}
clear_factory_cache();
uninit_apartment();
});
t.join();
}
return 0;
}This code causes an access violation reading exception.
After the fisrt time we call Consume(), DLLs were loaded, and an factory_cache_entry was set.
With WINRT_NO_MODULE_LOCK defined, the factory_cache_entry will not be added to the cache entry list.
As a result, the factory_cache_entry has no chance to be clear. However, without WINRT_NO_MODULE_LOCK, the factory_cache_entry could be clear by clear_factory_cache(). Windows system may unload DLLs further (i don't know exactly why and when), so an access violation could happen.
This is dangerous, as this code seems no harm to me, which an init_apartment() is always paired with an uninit_apartment(), and clear_factory_cache() when uninit_apartment() to ensure nothing is cache when there is no apartment.
I've found some ways to keep an extra MTA alive which prevent DLLs from being unloaded. Is this reliable and it it a good way?
IMO, this isn't good enough. If this code is inside a common lib, It assume that the application that using this lib must have a MTA alive all the time when running.