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:
parent
f7a403c21f
commit
ecbd634c9f
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user