https://bugs.winehq.org/show_bug.cgi?id=56182
Zeb Figura z.figura12@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Component|ntdll |ole32
--- Comment #9 from Zeb Figura z.figura12@gmail.com --- The application releases a proxy (IWiaDevMgr) from DllMain (DLL_PROCESS_DETACH, invoked through manual FreeLibrary()). This happens at a time when there are no threadpool threads active (and in practice any threads—such as the ones spawned earlier while creating or using the same proxy—have shut down due to the 5 second timeout.)
Calling a proxy method under normal circumstances requires an extra thread, which we wait for synchronously. This is because I_RpcSendReceive() [at least our understanding of it] is synchronous and encompasses the whole send/receive process, but we need the calling thread to be calling CoWaitForMultipleHandles().
This means we try to create and wait for a thread from DllMain(), which doesn't work. Manual testing confirms this part, and it also confirms that using RtlQueueWorkItem() on Windows doesn't work either.
Some tests show that you can do an arbitrary number of simultaneous proxy calls from within DllMain(), and they don't deadlock. This means one of three things that I can think of:
* Native is pre-allocating a new thread for each thread that has a proxy. This could be tested using thread reflection APIs, but I worry this comes too close to testing implementation details.
* Native is somehow interrupting the thread to perform reentrant calls. It's not through user APCs (I checked and manually created ones don't get delivered). It could be through suspension and debugging APIs, though this seems a bit less likely...
* Native is not using a separate thread.
Conceptually, this is the easiest and best solution. We are performing two waits here—one on a named pipe [which is supposed to be an LPC port on Windows, but this doesn't matter], and one for window message. Combining these waits is easy enough under normal circumstances; we could e.g. do async I/O on the pipe and use CoWaitForMultipleHandles(). [I don't know if an LPC port is similarly waitable...]
The problem is the rpcrt4 interface. I have no idea how to *do* this with rpcrt4. There is an async call interface, but I don't see any way to get a waitable handle out of it. But rpcrt4 is full of magic hidden glue, and there could easily be all number of secret incantations that ole32 is performing. I just don't see any obvious ones.
I'd like to be able to do something here, but I just can't without further direction.