1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-01-27 14:03:36 +03:00

threads: Fix double-checked locking in xmlInitParser

Hopefully work around the classic problem with double-checked locking:
Another thread could read xmlParserInitialized == 1 but doesn't see
other initialization results yet due to compiler or hardware reordering.
While unlikely, this seems theoretically possible.

The solution is to add a memory barrier after initializing the data but
before setting xmlParserInitialized. It might be enough to use a second
initialization flag which is only used inside the locked section and
update xmlParserInitialized after unlocking. But I haven't seen this
approach in many articles discussing this issue, so it's possibly
flawed as well.
This commit is contained in:
Nick Wellnhofer 2023-09-19 17:21:30 +02:00
parent f7a403c21f
commit ecbd634c9f

View File

@ -567,6 +567,8 @@ xmlGlobalInitMutexDestroy(void) {
*/
void
xmlInitParser(void) {
static int innerInitialized = 0;
/*
* Note that the initialization code must not make memory allocations.
*/
@ -575,7 +577,7 @@ xmlInitParser(void) {
xmlGlobalInitMutexLock();
if (xmlParserInitialized == 0) {
if (innerInitialized == 0) {
#if defined(_WIN32) && \
(!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
if (xmlFree == free)
@ -595,10 +597,12 @@ xmlInitParser(void) {
xmlRegisterDefaultOutputCallbacks();
#endif /* LIBXML_OUTPUT_ENABLED */
xmlParserInitialized = 1;
innerInitialized = 1;
}
xmlGlobalInitMutexUnlock();
xmlParserInitialized = 1;
}
/**