diff options
-rw-r--r-- | src/tracker-store/tracker-main.vala | 32 | ||||
-rw-r--r-- | src/tracker-store/tracker-store.vala | 59 |
2 files changed, 80 insertions, 11 deletions
diff --git a/src/tracker-store/tracker-main.vala b/src/tracker-store/tracker-main.vala index 478076278..1e8d1ddd2 100644 --- a/src/tracker-store/tracker-main.vala +++ b/src/tracker-store/tracker-main.vala @@ -37,6 +37,7 @@ License which can be viewed at: static MainLoop main_loop; static string log_filename; + static uint shutdown_timeout_id; static bool shutdown; static Tracker.Direct.Connection connection; @@ -52,11 +53,13 @@ License which can be viewed at: static File data_location; static File ontology_location; static string domain; + static bool disable_shutdown; const OptionEntry entries[] = { /* Daemon options */ { "version", 'V', 0, OptionArg.NONE, ref version, N_("Displays version information"), null }, { "verbosity", 'v', 0, OptionArg.INT, ref verbosity, N_("Logging, 0 = errors only, 1 = minimal, 2 = detailed and 3 = debug (default = 0)"), null }, + { "disable-shutdown", 's', 0, OptionArg.NONE, ref disable_shutdown, N_("Disable automatic shutdown"), null }, /* Indexer options */ { "force-reindex", 'r', 0, OptionArg.NONE, ref force_reindex, N_("Force a re-index of all content"), null }, @@ -180,6 +183,33 @@ License which can be viewed at: return connection; } + private static bool shutdown_timeout () { + message ("Store shutting down after timeout"); + do_shutdown (); + return GLib.Source.REMOVE; + } + + private static void idle_cb () { + /* Do not perform shutdown in case of exotic buses */ + if (Tracker.IPC.bus () != GLib.BusType.SESSION) + return; + if (shutdown_timeout_id != 0) + return; + if (disable_shutdown) + return; + + message ("Store is idle, setting shutdown timeout"); + shutdown_timeout_id = GLib.Timeout.add_seconds (30, shutdown_timeout); + } + + private static void busy_cb () { + if (shutdown_timeout_id == 0) + return; + message ("Store is busy, removing shutdown timeout"); + GLib.Source.remove (shutdown_timeout_id); + shutdown_timeout_id = 0; + } + static int main (string[] args) { Intl.setlocale (LocaleCategory.ALL, ""); @@ -265,7 +295,7 @@ License which can be viewed at: var notifier = Tracker.DBus.register_notifier (); - Tracker.Store.init (config); + Tracker.Store.init (config, idle_cb, busy_cb); /* Make Tracker available for introspection */ if (!Tracker.DBus.register_objects ()) { diff --git a/src/tracker-store/tracker-store.vala b/src/tracker-store/tracker-store.vala index 03cc8078a..f7b03a601 100644 --- a/src/tracker-store/tracker-store.vala +++ b/src/tracker-store/tracker-store.vala @@ -39,6 +39,11 @@ public class Tracker.Store { public delegate void SparqlQueryInThread (Sparql.Cursor cursor) throws Error; + public delegate void StateCallback (); + static unowned StateCallback idle_cb; + static unowned StateCallback busy_cb; + static bool busy; + class CursorTask { public Sparql.Cursor cursor; public unowned SourceFunc callback; @@ -61,11 +66,12 @@ public class Tracker.Store { Idle.add (() => { task.callback (); + update_state (); return false; }); } - public static void init (Tracker.Config config_p) { + public static void init (Tracker.Config config_p, StateCallback idle, StateCallback busy) { string max_task_time_env = Environment.get_variable ("TRACKER_STORE_MAX_TASK_TIME"); if (max_task_time_env != null) { max_task_time = int.parse (max_task_time_env); @@ -88,6 +94,9 @@ public class Tracker.Store { ThreadPool.set_max_unused_threads (2); config = config_p; + idle_cb = idle; + busy_cb = busy; + idle_cb (); } public static void shutdown () { @@ -158,30 +167,41 @@ public class Tracker.Store { // Ignore harmless error } + update_state (); + yield; if (task.error != null) throw task.error; } + private static void pre_update () { + n_updates++; + update_state (); + ensure_signal_timeout (); + } + + private static void post_update () { + n_updates--; + update_state (); + } + public static async void sparql_update (Tracker.Direct.Connection conn, string sparql, int priority, string client_id) throws Error { if (!active) throw new Sparql.Error.UNSUPPORTED ("Store is not active"); - n_updates++; - ensure_signal_timeout (); + pre_update (); var cancellable = create_cancellable (client_id); yield conn.update_async (sparql, priority, cancellable); - n_updates--; + post_update (); } public static async Variant sparql_update_blank (Tracker.Direct.Connection conn, string sparql, int priority, string client_id) throws Error { if (!active) throw new Sparql.Error.UNSUPPORTED ("Store is not active"); - n_updates++; - ensure_signal_timeout (); + pre_update (); var cancellable = create_cancellable (client_id); var nodes = yield conn.update_blank_async (sparql, priority, cancellable); - n_updates--; + post_update (); return nodes; } @@ -189,11 +209,10 @@ public class Tracker.Store { public static async void queue_turtle_import (Tracker.Direct.Connection conn, File file, string client_id) throws Error { if (!active) throw new Sparql.Error.UNSUPPORTED ("Store is not active"); - n_updates++; - ensure_signal_timeout (); + pre_update (); var cancellable = create_cancellable (client_id); yield conn.load_async (file, cancellable); - n_updates--; + post_update (); } public static void unreg_batches (string client_id) { @@ -202,6 +221,7 @@ public class Tracker.Store { if (cancellable != null) { cancellable.cancel (); client_cancellables.remove (client_id); + update_state (); } } @@ -216,10 +236,29 @@ public class Tracker.Store { Tracker.Store.active = true; } + private static void update_state () { + bool cur_busy; + + cur_busy = (!Tracker.Store.active || /* Keep busy while paused */ + n_updates != 0 || /* There are updates */ + cursor_pool.unprocessed () > 0 || /* Select cursor pool is busy */ + cursor_pool.get_num_threads () > 0); + + if (busy == cur_busy) + return; + + busy = cur_busy; + if (busy) + busy_cb (); + else + idle_cb (); + } + private static void on_statements_committed () { Tracker.Events.transact (); Tracker.Writeback.transact (); check_graph_updated_signal (); + update_state (); } private static void on_statements_rolled_back () { |