[PATCH v2 0/2] MR3372: ole32: Leave the RunningObjectTable Critical Section before unmarshalling object stream
In certain circumstances unmarshalling an object stream from the RunningObjectTable can cause the unmarshalling routines to interrogate the same table (maybe to resolve a dependant object?) in a different thread causing a deadlock while getting the critical section lock. Leaving the Critical Section before unmarshalling the object stream solve this problem. Visual Studio 2019 deadlock on start without this. I'm not sure how to test this properly. Also add debug info for this critical section so it show a significant name in the log. Signed-off-by: Lorenzo Ferrillo <lorenzofersteam(a)live.it> -- v2: ole32: Add debug info to RunningObjectTable critical section ole32: Leave the RunningObjectTable Critical Section before umarshalling object https://gitlab.winehq.org/wine/wine/-/merge_requests/3372
From: Lorenzo Ferrillo <lorenzofersteam(a)live.it> Sometimes umarshalling an object from the RunningObjectTable can cause the routine to access the table back inside another thread, causing a deadlock. Visual Studio 2019 is an example of this behaviour. Signed-off-by: Lorenzo Ferrillo <lorenzofersteam(a)live.it> --- dlls/ole32/moniker.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c index ec026758b2f..06a2ef8de9c 100644 --- a/dlls/ole32/moniker.c +++ b/dlls/ole32/moniker.c @@ -541,13 +541,14 @@ RunningObjectTableImpl_GetObject( IRunningObjectTable* iface, { IStream *pStream; hr = create_stream_on_mip_ro(rot_entry->object, &pStream); + LeaveCriticalSection(&This->lock); + if (hr == S_OK) { hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)ppunkObject); IStream_Release(pStream); } - LeaveCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, moniker_data); return hr; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3372
From: Lorenzo Ferrillo <lorenzofersteam(a)live.it> So it's possible to easily debug deadlocks involving the Internal ROT object Signed-off-by: Lorenzo Ferrillo <lorenzofersteam(a)live.it> --- dlls/ole32/moniker.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c index 06a2ef8de9c..a56039d05b6 100644 --- a/dlls/ole32/moniker.c +++ b/dlls/ole32/moniker.c @@ -707,10 +707,20 @@ static const IRunningObjectTableVtbl VT_RunningObjectTableImpl = RunningObjectTableImpl_EnumRunning }; + +static RunningObjectTableImpl rot; + +static RTL_CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &rot.lock, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": RunningObjectTable_section") } +}; + static RunningObjectTableImpl rot = { .IRunningObjectTable_iface.lpVtbl = &VT_RunningObjectTableImpl, - .lock.LockCount = -1, + .lock = { &critsect_debug, -1, 0, 0, 0, 0 }, .rot = LIST_INIT(rot.rot), }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3372
participants (2)
-
Lorenzo Ferrillo -
Lorenzo Ferrillo (@llde)