[librsvg: 51/90] (#445): Initialize libxml2 so multithreaded tests don't deadlock



commit a6d6f381a72fdbc62da7e324cf77b44fbabbd44d
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Mar 19 18:39:11 2019 -0600

    (#445): Initialize libxml2 so multithreaded tests don't deadlock
    
    This is really a best-effort kind of thing.  Libxml2 really wants to
    be xmlInitParser() to be called from the main thread :(
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/445

 rsvg_internals/src/xml2.rs      |  2 ++
 rsvg_internals/src/xml2_load.rs | 11 +++++++++++
 2 files changed, 13 insertions(+)
---
diff --git a/rsvg_internals/src/xml2.rs b/rsvg_internals/src/xml2.rs
index d6975683..4ad7a652 100644
--- a/rsvg_internals/src/xml2.rs
+++ b/rsvg_internals/src/xml2.rs
@@ -163,6 +163,8 @@ pub type xmlInputCloseCallback = Option<unsafe extern "C" fn(
 pub type xmlCharEncoding = libc::c_int;
 
 extern "C" {
+    pub fn xmlInitParser();
+
     pub fn xmlCreateIOParserCtxt(
         sax: xmlSAXHandlerPtr,
         user_data: *mut libc::c_void,
diff --git a/rsvg_internals/src/xml2_load.rs b/rsvg_internals/src/xml2_load.rs
index 4e388405..ba160c9f 100644
--- a/rsvg_internals/src/xml2_load.rs
+++ b/rsvg_internals/src/xml2_load.rs
@@ -10,6 +10,7 @@ use std::ptr;
 use std::rc::Rc;
 use std::slice;
 use std::str;
+use std::sync::Once;
 
 use glib::translate::*;
 
@@ -303,6 +304,14 @@ unsafe extern "C" fn stream_ctx_close(context: *mut libc::c_void) -> libc::c_int
     ret
 }
 
+fn init_libxml2() {
+    static ONCE: Once = Once::new();
+
+    ONCE.call_once(|| unsafe {
+        xmlInitParser();
+    });
+}
+
 struct Xml2Parser {
     parser: xmlParserCtxtPtr,
     gio_error: Rc<RefCell<Option<glib::Error>>>,
@@ -315,6 +324,8 @@ impl Xml2Parser {
         stream: gio::InputStream,
         cancellable: Option<&gio::Cancellable>,
     ) -> Result<Xml2Parser, ParseFromStreamError> {
+        init_libxml2();
+
         // The Xml2Parser we end up creating, if
         // xmlCreateIOParserCtxt() is successful, needs to hold a
         // location to place a GError from within the I/O callbacks


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