From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index a31d586a5b6..173df2ee73b 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -227,6 +227,7 @@ struct display_device
struct gpu { + LONG refcount; struct list entry; LUID luid; unsigned int adapter_count; @@ -239,6 +240,7 @@ struct adapter struct display_device dev; LUID gpu_luid; unsigned int id; + struct gpu *gpu; const WCHAR *config_key; unsigned int mode_count; DEVMODEW *modes; @@ -465,6 +467,18 @@ static void release_display_device_init_mutex( HANDLE mutex ) NtClose( mutex ); }
+static struct gpu *gpu_acquire( struct gpu *gpu ) +{ + InterlockedIncrement( &gpu->refcount ); + return gpu; +} + +static void gpu_release( struct gpu *gpu ) +{ + if (!InterlockedDecrement( &gpu->refcount )) + free( gpu ); +} + static struct adapter *adapter_acquire( struct adapter *adapter ) { InterlockedIncrement( &adapter->refcount ); @@ -475,6 +489,7 @@ static void adapter_release( struct adapter *adapter ) { if (!InterlockedDecrement( &adapter->refcount )) { + gpu_release( adapter->gpu ); free( adapter->modes ); free( adapter ); } @@ -1680,7 +1695,7 @@ static void clear_display_devices(void) { gpu = LIST_ENTRY( list_head( &gpus ), struct gpu, entry ); list_remove( &gpu->entry ); - free( gpu ); + gpu_release( gpu ); } }
@@ -1725,7 +1740,8 @@ static BOOL update_display_cache_from_registry(void)
if (!read_display_adapter_settings( adapter_id, adapter )) { - adapter_release( adapter ); + free( adapter->modes ); + free( adapter ); break; }
@@ -1792,6 +1808,7 @@ static BOOL update_display_cache_from_registry(void) NtClose( gpu_key ); continue; } + gpu->refcount = 1;
if ((prop_key = reg_open_key( gpu_key, devpropkey_gpu_luidW, sizeof(devpropkey_gpu_luidW) ))) @@ -1804,7 +1821,10 @@ static BOOL update_display_cache_from_registry(void) LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) { if (!memcmp( &adapter->gpu_luid, &gpu->luid, sizeof(LUID) )) + { + adapter->gpu = gpu_acquire( gpu ); gpu->adapter_count++; + } }
list_add_tail( &gpus, &gpu->entry );