[libxml++] Parser: Make it thread-safe.



commit e662e32f2943ef1b71101ccb1a9e7a0b585c39a2
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Tue Aug 28 16:13:35 2012 +0200

    Parser: Make it thread-safe.
    
    * configure.ac: Require glibmm-2.4 >= 2.32.0.
    * libxml++/parsers/parser.cc: Protect all accesses to extra_parser_data with
    a Glib::Threads::Mutex. Bug #681467.

 ChangeLog                  |    8 ++++++++
 configure.ac               |    2 +-
 libxml++/parsers/parser.cc |   11 +++++++++++
 3 files changed, 20 insertions(+), 1 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c02f485..5aa8735 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-08-28  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+
+	Parser: Make it thread-safe.
+
+	* configure.ac: Require glibmm-2.4 >= 2.32.0.
+	* libxml++/parsers/parser.cc: Protect all accesses to extra_parser_data with
+	a Glib::Threads::Mutex. Bug #681467.
+
 2012-08-10  Kjell Ahlstedt  <kjell ahlstedt bredband net>
 
 	Document: Make the Document(xmlDoc*) constructor public.
diff --git a/configure.ac b/configure.ac
index 5260e85..5e0b4b7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,7 +28,7 @@ AC_PROG_CXX
 LT_PREREQ([2.2.6])
 LT_INIT([dlopen win32-dll disable-static])
 
-AC_SUBST([LIBXMLXX_MODULES], ['libxml-2.0 >= 2.6.1 glibmm-2.4 >= 2.4.0'])
+AC_SUBST([LIBXMLXX_MODULES], ['libxml-2.0 >= 2.6.1 glibmm-2.4 >= 2.32.0'])
 PKG_CHECK_MODULES([LIBXMLXX], [$LIBXMLXX_MODULES])
 
 AC_LANG([C++])
diff --git a/libxml++/parsers/parser.cc b/libxml++/parsers/parser.cc
index b1055b7..66e1d61 100644
--- a/libxml++/parsers/parser.cc
+++ b/libxml++/parsers/parser.cc
@@ -10,6 +10,7 @@
 
 #include <memory> //For auto_ptr.
 #include <map>
+#include <glibmm/threads.h> // For Glib::Threads::Mutex. Needed until the next API/ABI break.
 
 //TODO: See several TODOs in parser.h for changes at the next API/ABI break.
 
@@ -30,15 +31,20 @@ struct ExtraParserData
 };
 
 std::map<const xmlpp::Parser*, ExtraParserData> extra_parser_data;
+// Different Parser instances may run in different threads.
+// Accesses to extra_parser_data must be thread-safe.
+Glib::Threads::Mutex extra_parser_data_mutex;
 
 void on_parser_error(const xmlpp::Parser* parser, const Glib::ustring& message)
 {
+  Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
   //Throw an exception later when the whole message has been received:
   extra_parser_data[parser].parser_error_ += message;
 }
 
 void on_parser_warning(const xmlpp::Parser* parser, const Glib::ustring& message)
 {
+  Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
   //Throw an exception later when the whole message has been received:
   extra_parser_data[parser].parser_warning_ += message;
 }
@@ -56,6 +62,7 @@ Parser::~Parser()
 {
   release_underlying();
   delete exception_;
+  Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
   extra_parser_data.erase(this);
 }
 
@@ -81,12 +88,14 @@ bool Parser::get_substitute_entities() const
 
 void Parser::set_throw_messages(bool val)
 {
+  Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
   extra_parser_data[this].throw_parser_messages_ = val;
   extra_parser_data[this].throw_validity_messages_ = val;
 }
 
 bool Parser::get_throw_messages() const
 {
+  Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
   return extra_parser_data[this].throw_parser_messages_;
 }
 
@@ -101,6 +110,7 @@ void Parser::initialize_context()
   //Turn on/off validation:
   context_->validate = (validate_ ? 1 : 0);
 
+  Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
   if (context_->sax && extra_parser_data[this].throw_parser_messages_)
   {
     //Tell the parser context about the callbacks.
@@ -164,6 +174,7 @@ void Parser::check_for_validity_messages() // Also checks parser messages
   bool parser_msg = false;
   bool validity_msg = false;
 
+  Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
   if (!extra_parser_data[this].parser_error_.empty())
   {
     parser_msg = true;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]