RFR: 8301846: Invalid TargetDataLine after screen lock when using JFileChooser or COM library [v3]

Sergey Bylokhov serb at openjdk.org
Wed Jul 26 23:32:52 UTC 2023


On Wed, 26 Jul 2023 21:16:11 GMT, Alexey Ivanov <aivanov at openjdk.org> wrote:

>>> > Probably… But it is still incorrect. Initialising COM on a thread doesn't mean you can call COM object methods from any thread in your application.
>>> 
>>> Note that "Objects created on a COM thread in a multithread apartment (MTA) must be able to receive method calls from other threads at any time", so if we initialisethe devices on one thread using COM they will be avaliable on other threads as well.
>> 
>> But from the threads where you initialised COM as MTA.
>> 
>> The docs for `CoInitializeEx` clearly state you have to initialise COM before you can use it. Thus, calling methods of COM objects from an arbitrary thread in your application is wrong, isn't it?
>> 
>>> But the spec for DirectSoundEnumerate says nothing about COM... But from some examples I see ppl wrap it by the CoInitializeEx(NULL, COINIT_MULTITHREADED)/CoUninitialize();
>>> 
>>> Noe sure we can call CoInitializeEx on the main thread.
>> 
>> It's for any thread not only the main thread… You can all `AudioSystem.getMixerInfo` from any thread in a Java app, if `DirectSoundEnumerate` needs COM to be initialised even though the documentation doesn't mention it, we have to initalise COM. Thus there are two options:
>> 
>> 1. Call `CoInitializeEx`, enumerate devices, and call `CoUninitialize`.
>> 2. Create an executor service which initialises COM on its worker thread, enumerate devices on the worker thread and return the devices. The worker thread may terminate (after it calls `CoUninitialize`) if it doesn't receive more requests in a period of time.
>
>> > > 3. Do another CoInitialize before call  :- not a good approach
>> > 
>> > Yet it does not break the rules: you can initialise COM, call an API and then call [`CoUninitialize`](https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-couninitialize). If you don't keep any references to COM objects, it is valid.
>> 
>> Tried this approach and it works, we may need to do the similar approach for another function `DAUDIO_GetDirectAudioDeviceDescription` because this also calling `DirectSoundEnumerateW `& `DirectSoundCaptureEnumerateW `
> 
> Does this approach return full names for devices, without truncating them?

But if that code requare com my expectation would be that they call CoInitialize/CoUninitialize.

This CoInitialize initially was added here https://bugs.openjdk.org/browse/JDK-6950553 (check the stack trace),
https://github.com/openjdk/jdk/commit/b8b9c35567919f9f375cc3610d823524cf5b8582 can we check that the DAUDIO_GetDirectAudioDeviceDescription  is really uses that com object w/o initialisation?
>1. Call CoInitializeEx, enumerate devices, and call CoUninitialize.
>2. Create an executor service which initialises COM on its worker thread, enumerate devices on the worker thread and return the devices. The worker thread may terminate (after it calls CoUninitialize) if it doesn't receive more requests in a period of time.

We can try reuse the "Filechooser.invokeCom" machinery, but I do not think I like it.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/14898#discussion_r1275574660



More information about the client-libs-dev mailing list