[v4 PATCH 1/2] dwrite: Protect cached fontface list when accessed from multiple threads
Sebastian Lackner
sebastian at fds-team.de
Thu Aug 10 11:04:42 CDT 2017
On 10.08.2017 15:41, Nikolay Sivov wrote:
> @@ -861,6 +877,10 @@ HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * co
> const void *cached_key;
> IDWriteFontFile *file;
>
> + if (IDWriteFontFace4_AddRef(cached->fontface) == 1)
> + continue;
> + IDWriteFontFace4_Release(cached->fontface);
This will not work as expected. The refcount also matters when the object is
about to be destroyed. There could be multiple threads running
factory_get_cached_fontface() before _Release() can finally remove the fontface
from the list. Please note that always calling _Release() also wouldn't be
correct because it would run the destructor twice.
It is not really necessary to access the private structs from other parts of
dwrite, but you should either:
* change AddRef to use something like interlocked_dec_if_nonzero (see ntdll/sync.c)
* implement the check in QueryInterface (manually run InterlockedDecrement to
decrement the refcount without going through the destructor)
There are probably also other ways, for example using a flag to make sure the
destructor is not called twice.
Best regards,
Sebastian
More information about the wine-devel
mailing list