[xml] Race condition in xsltInit (thread safety)
- From: "Christopher R. Palmer" <crpalmer vivisimo com>
- To: xml gnome org
- Subject: [xml] Race condition in xsltInit (thread safety)
- Date: Mon, 20 Feb 2006 13:13:57 -0500
Hi,
I am using 1.1.15 of libxslt with multiple threads and I am seeing
occasional crashes in the (libc) free function. The stack traces look
something like:
xsltParseStylesheetDoc
...
xsltNewStylesheet
xslInit
xsltRegisterAllExtras
xsltRegisterExtModuleFunction
...
xmlHashUpdateEntry3
...
[free]
Digging into this a little more, it looks like xsltInit is called every
time that a new stylesheet is parsed. xsltInit uses xsltRegisterAllExtras
which always updates all of the hash entries and the hash function is (not
surprisingly) not thread safe for updates.
CVS tells me that xsltInit was changed to fix bug #165201 (calling xsltInit
multiple times) where previously it had a local static initialized flag.
The best fix I can suggest is to export xsltInit and have a static
initialized flag. To not break the fix of bug #165201, add an internal
function to signal that the library is no longer initialized.
I've attached such a patch for possible inclusion in the code base.
Cheers,
Chris.
diff -r --unified orig/libxslt-1.1.15/libxslt/extensions.c libxslt-1.1.15/libxslt/extensions.c
Index: orig/libxslt-1.1.15/libxslt/extensions.c
--- orig/libxslt-1.1.15/libxslt/extensions.c 2005-01-15 18:00:52.000000000 -0500
+++ libxslt-1.1.15/libxslt/extensions.c 2006-02-20 12:42:52.000000000 -0500
@@ -1881,6 +1881,8 @@
xmlHashFree(xsltModuleHash, NULL);
xsltModuleHash = NULL;
}
+
+ xsltUninit();
}
static void
diff -r --unified orig/libxslt-1.1.15/libxslt/xslt.c libxslt-1.1.15/libxslt/xslt.c
Index: orig/libxslt-1.1.15/libxslt/xslt.c
--- orig/libxslt-1.1.15/libxslt/xslt.c 2005-08-25 07:28:07.000000000 -0400
+++ libxslt-1.1.15/libxslt/xslt.c 2006-02-20 12:43:53.000000000 -0500
@@ -148,9 +148,26 @@
* Initializes the processor (e.g. registers built-in extensions,
* etc.)
*/
-static void
+
+static int initialized = 0;
+
+void
xsltInit (void) {
- xsltRegisterAllExtras();
+ if (initialized == 0) {
+ initialized = 1;
+ xsltRegisterAllExtras();
+ }
+}
+
+/**
+ * xsltUninit
+ *
+ * Uninitializes the processor.
+ */
+
+void
+xsltUninit (void) {
+ initialized = 0;
}
/**
diff -r --unified orig/libxslt-1.1.15/libxslt/xslt.h libxslt-1.1.15/libxslt/xslt.h
Index: orig/libxslt-1.1.15/libxslt/xslt.h
--- orig/libxslt-1.1.15/libxslt/xslt.h 2004-08-19 02:49:42.000000000 -0400
+++ libxslt-1.1.15/libxslt/xslt.h 2006-02-20 12:45:38.000000000 -0500
@@ -83,6 +83,13 @@
XSLTPUBVAR const int xsltLibxmlVersion;
/*
+ * Global initialization function.
+ */
+
+XSLTPUBFUN void XSLTCALL
+ xsltInit (void);
+
+/*
* Global cleanup function.
*/
XSLTPUBFUN void XSLTCALL
diff -r --unified orig/libxslt-1.1.15/libxslt/xsltInternals.h libxslt-1.1.15/libxslt/xsltInternals.h
--- orig/libxslt-1.1.15/libxslt/xsltInternals.h 2005-03-29 05:40:26.000000000 -0500
+++ libxslt-1.1.15/libxslt/xsltInternals.h 2006-02-20 12:47:35.000000000 -0500
@@ -694,6 +694,14 @@
xmlNodePtr node);
XSLTPUBFUN void XSLTCALL
xsltFreeAVTList (void *avt);
+
+/*
+ * Extra function for successful xsltCleanupGlobals / xsltInit sequence.
+ */
+
+XSLTPUBFUN void XSLTCALL
+ xsltUninit (void);
+
#ifdef __cplusplus
}
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]