vcl::Window::dispose deadlock

Michael Stahl mstahl at redhat.com
Fri Jun 12 05:48:58 PDT 2015


On 09.06.2015 17:31, Michael Meeks wrote:
> On Tue, 2015-06-09 at 11:36 +0200, Michael Stahl wrote:

>>  or perhaps it would also work to have a dedicated thread that does nothing
>> other than handle the special thread affine Win32 create/destroy-window
>> messages and never takes a lock.
> 
> 	This approach OTOH is really rather easy ;-) I imagine having a
> SalComWndProc custom thread would simplify a number of code-paths
> really. I guess the concern there would be performance, but then - hard
> to know what that is until we benchmark it - Windows appears to have a
> very large number of similar "GDI worker" type threads itself lying
> around in each application these days; we even have threads for
> high-frequency timers which improves performance ;-)

i looked into that a bit and it does not appear all that easy.

the problematic thread affine Win32 objects are Windows and DCs.

so let's imagine that...

main thread has magic window with custom lpfnWndProc
affinity thread has magic window with custom lpfnWndProc

all threads SendMessage these to the affinity thread instead of main thread:
SAL_MSG_GETDC SAL_MSG_RELEASEDC
SAL_MSG_RECREATEHWND SAL_MSG_RECREATECHILDHWND
SAL_MSG_CREATEFRAME SAL_MSG_DESTROYFRAME

the affinity thread handles these messages itself,
and *never* acquires SolarMutex to avoid the deadlock.

problem: if the HWND is created by the affinity thread, its
window messages will be sent to the affinity thread; they cannot
all be handled there because that would require the SolarMutex.

so the affinity thread needs to forward any message sent to an HWND
to the main thread so the actual handler runs there.

it cannot use SendMessage to do that, because that would block
until the message is handled, and handling it may require SolarMutex.

but if it uses PostMessage, and the message contains pointers,
how do we know that the stuff that is pointed to is still alive
when we remove the window message from the affinity thread's queue?

the objects pointed to are owned by the sender of the message.

this would require some custom marshalling and memory management,
and because every kind of message has different argument types this
is a can of worms, not to mention that new Windows releases could add
new message types that we don't know about yet.

we could forward just the messages that we have custom handlers for,
and handle the others in the affinity thread, but that would mean
(since the affinity thread can't block) handling the messages out
of order [see the call to DefWindowProcW in salframe.cxx].

another problem: GetMessage(..., hwnd, ...) / PeekMessage(..., hwnd,...)
on the main thread will no longer work because the hwnd is not created
by the main thread.  such calls exist in salframe.cxx.

tl;dr: generic forwarding of Window messages to another thread feels
like fundamentally working against Win32 architecture and i wouldn't
recommend trying it at home

better to handle all Window messages in the affinity thread, and we
could perhaps design a *custom* protocol at a higher level (VCL) between
the two threads - but that sounds like a lot of work for not enough
gain, compared with the other approach of moving everything to the main
thread.




More information about the LibreOffice mailing list