[libhttpseverywhere/fullxml] context: threaded xml loading



commit 05ac2f0d5619f42228ec9f57725b77a454eaf327
Author: grindhold <grindhold gmx net>
Date:   Mon Sep 18 21:41:53 2017 +0200

    context: threaded xml loading

 src/context.vala |  101 +++++++++++++++++++++++++++++++++---------------------
 test/main.vala   |   28 ++-------------
 2 files changed, 66 insertions(+), 63 deletions(-)
---
diff --git a/src/context.vala b/src/context.vala
index 08a5baa..779ac46 100644
--- a/src/context.vala
+++ b/src/context.vala
@@ -80,52 +80,75 @@ namespace HTTPSEverywhere {
          * Create a new library context object.
          */
         public Context() {
+            try {
+                new Thread<int>.try("rulesets", this.init);
+            } catch (Error e) {
+                warning("Could not initialize HTTPSEverywhere: %s", e.message);
+            }
         }
 
         /**
+         * Initialization finished
+         *
+         * This signal is being triggered when all ruesets have
+         * been loaded into memory and the context can subsequently
+         * be asked to perform queries on HTTPSEverywheres data.
+         */
+        public signal void rdy(Error? e);
+
+        /**
          * This function initializes HTTPSEverywhere by loading
          * the rulesets from the filesystem.
          */
-        public async void init(Cancellable? cancellable = null) throws IOError {
-            initialized = false;
+        private int init() {
+            lock (this.initialized) {
+                IOError e;
+                try {
+                    initialized = false;
 
-            targets = new Gee.HashMap<Target,Gee.ArrayList<uint>>();
-            rulesets = new Gee.HashMap<int, Ruleset>();
-            cache = new Gee.ArrayList<Target>();
+                    targets = new Gee.HashMap<Target,Gee.ArrayList<uint>>();
+                    rulesets = new Gee.HashMap<int, Ruleset>();
+                    cache = new Gee.ArrayList<Target>();
 
-            ignore_list = new Gee.ArrayList<uint>();
+                    ignore_list = new Gee.ArrayList<uint>();
 
-            var datapaths = new Gee.ArrayList<string>();
+                    var datapaths = new Gee.ArrayList<string>();
 
-            // Specify the paths to search for rules in
-            datapaths.add(Path.build_filename(Environment.get_user_data_dir(),
-                                              "libhttpseverywhere", rulesets_file));
-            foreach (string dp in Environment.get_system_data_dirs())
-                datapaths.add(Path.build_filename(dp, "libhttpseverywhere", rulesets_file));
+                    // Specify the paths to search for rules in
+                    datapaths.add(Path.build_filename(Environment.get_user_data_dir(),
+                                                      "libhttpseverywhere", rulesets_file));
+                    foreach (string dp in Environment.get_system_data_dirs())
+                        datapaths.add(Path.build_filename(dp, "libhttpseverywhere", rulesets_file));
 
-            // local rules in repo dir to test data without installation
-            datapaths.add(Path.build_filename(Environment.get_current_dir(), "..", "data", rulesets_file));
+                    // local rules in repo dir to test data without installation
+                    datapaths.add(Path.build_filename(Environment.get_current_dir(), "..", "data", 
rulesets_file));
 
-            bool success = false;
+                    bool success = false;
 
-            foreach (string dp in datapaths) {
-                this.ruleset_xml = Xml.Parser.parse_file(dp);
-                if (this.ruleset_xml == null)
-                    continue;
-                success = true;
-                break;
-            }
-            if (!success) {
-                string locations = "\n";
-                foreach (string location in datapaths)
-                    locations += "%s\n".printf(location);
-                critical("Could not find any suitable database in the following locations:%s",
-                         locations);
-                return;
+                    foreach (string dp in datapaths) {
+                        this.ruleset_xml = Xml.Parser.parse_file(dp);
+                        if (this.ruleset_xml == null)
+                            continue;
+                        success = true;
+                        break;
+                    }
+                    if (!success) {
+                        string locations = "\n";
+                        foreach (string location in datapaths)
+                            locations += "%s\n".printf(location);
+                        critical("Could not find any suitable database in the following locations:%s",
+                                 locations);
+                        return 1;
+                    }
+                    this.load_rulesets();
+                    initialized = true;
+                } catch (IOError e) {
+                    GLib.Idle.add(()=>{this.rdy(e); return false;});
+                    return 1;
+                }
             }
-
-            load_rulesets();
-            initialized = true;
+            GLib.Idle.add(()=>{this.rdy(null); return false;});
+            return 0;
         }
 
         /**
diff --git a/test/main.vala b/test/main.vala
index 338c6f8..9f41de6 100644
--- a/test/main.vala
+++ b/test/main.vala
@@ -42,9 +42,11 @@ namespace HTTPSEverywhereTest {
             Test.add_func("/httpseverywhere/context/rewrite", () => {
                 var context = new Context();
                 var m = new MainLoop();
-                context.init.begin(null, (obj, res) => {
+                context.rdy.connect((e) => {
+                    if (e != null) {
+                        GLib.assert_not_reached();
+                    }
                     try {
-                        context.init.end(res);
                         var result = context.rewrite("http://example.com";);
                         assert(result == "http://example.com/"; || result == "https://example.com/";);
                         assert(context.has_https("http://example.com";) == result.has_prefix("https://";));
@@ -56,28 +58,6 @@ namespace HTTPSEverywhereTest {
                 m.run();
             });
 
-            // TODO: check wheter xml-parser may be used asnychronously
-            //       if yes, reactivate. if not remove this test
-            /*Test.add_func("/httpseverywhere/context/cancel_init", () => {
-                var loop = new MainLoop();
-                var context = new Context();
-                var cancellable = new Cancellable();
-
-                context.init.begin(cancellable, (obj, res) => {
-                    try {
-                        context.init.end(res);
-                        assert_not_reached();
-                    } catch (Error e) {
-                        assert(e is IOError.CANCELLED);
-                        assert(cancellable.is_cancelled());
-                        loop.quit();
-                    }
-                });
-
-                cancellable.cancel();
-                loop.run();
-            });*/
-
             Test.add_func("/httpseverywhere/context/rewrite_before_init", () => {
                 if (Test.subprocess()) {
                     /* Should emit a critical since init has not been called. */


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