Use C11 atomics if available. Otherwise, fall back to pthread mutex
inlined in xmlDict struct or Win32 atomics.
This should fix lock contention reported in #970.
Relying on a plain integer flag, with no synchronization primitives does
not give thread-safe initialization. All reads & writes of the
xmlSchemaTypesInitialized flag need to be protected by a mutex to ensure
suitable memory barriers & thus correct ordering wrt any speculative
execution.
A separate internal initializer tied to xmlParserInit is used to create
the mutex used for synchronization, similarly to how catalog.c works.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Relying on a plain integer flag, with no synchronization primitives does
not give thread-safe initialization. All reads & writes of the
xmlSchemaTypesInitialized flag need to be protected by a mutex to ensure
suitable memory barriers & thus correct ordering wrt any speculative
execution.
A separate internal initializer tied to xmlParserInit is used to create
the mutex used for synchronization, similarly to how catalog.c works.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Support for RELAX NG used to be enabled together with XML Schema support
(--with-schemas). Now there's a separate option and a new feature macro
LIBXML_RELAXNG_ENABLED.
Don't treat "main" thread specially. This simplifies access to
thread-specific data.
xmlGetGlobalState can now also fail on the former main thread, leading
to an unrecoverable condition if malloc fails.
The globals were never defined in public header files when compiling
with thread support. Now they're only defined in a legacy build.
Move TlsFree to DllMain to make cleanup more robust on Windows.
Obsoletes #1.
On Linux, we tried to detect the presence of libpthread to disable
things like locks. This questionable hack doesn't work since glibc 2.34
which merged libpthread into libc.
Remove calls to generic error handler or use stderr for
- legacy deprecation warnings
- nanohttp, nanoftp in standalone mode
- memory debug messages
Use xmlRaiseMemoryError.
Remove TODO macro.
Don't raise errors in xmlmodule.c.
Linking executables will fail on systems with glibc < 2.34 without
declaring these symbols as weak references.
In commit c19771c1f1 these references
were moved to globals.c from threads.c, but the `#pragma weak`
declarations were lost in the process.
Also removing unneeded weak declarations from threads.c.
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.
GCC 12 fixed -Waddress warnings for inline functions, resulting in
warnings when comparing pthread_equal with NULL. Simply remove the
check and assume that pthread_equal is available if all the other
functions are. This code is only enabled on Linux anyway.