[tracker/libtracker-miner-improved-pausing: 1/2] libtracker-miner: Added APIs for pausing miners during process life time
- From: Martyn James Russell <mr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/libtracker-miner-improved-pausing: 1/2] libtracker-miner: Added APIs for pausing miners during process life time
- Date: Tue, 24 May 2011 14:26:33 +0000 (UTC)
commit e47b0239573feca7e5404663bc6b7f4ff2ef613e
Author: Martyn Russell <martyn lanedo com>
Date: Mon May 16 12:22:11 2011 +0100
libtracker-miner: Added APIs for pausing miners during process life time
This adds:
- tracker_miner_manager_pause_for_process()
This also adds the dbus equivalent APIs.
Note, this feature is only available using D-Bus, there is no C API for
watching processes available.
data/dbus/tracker-miner.xml | 6 +
src/libtracker-miner/tracker-miner-manager.c | 74 +++++++++++++
src/libtracker-miner/tracker-miner-manager.h | 4 +
src/libtracker-miner/tracker-miner-object.c | 152 ++++++++++++++++++++++----
4 files changed, 215 insertions(+), 21 deletions(-)
---
diff --git a/data/dbus/tracker-miner.xml b/data/dbus/tracker-miner.xml
index 901943f..00bb5f2 100644
--- a/data/dbus/tracker-miner.xml
+++ b/data/dbus/tracker-miner.xml
@@ -26,6 +26,12 @@
<arg type="s" name="reason" direction="in" />
<arg type="i" name="cookie" direction="out" />
</method>
+ <method name="PauseForProcess">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+ <arg type="s" name="application" direction="in" />
+ <arg type="s" name="reason" direction="in" />
+ <arg type="i" name="cookie" direction="out" />
+ </method>
<method name="Resume">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg type="i" name="cookie" direction="in" />
diff --git a/src/libtracker-miner/tracker-miner-manager.c b/src/libtracker-miner/tracker-miner-manager.c
index e1cb7dd..0c92ba3 100644
--- a/src/libtracker-miner/tracker-miner-manager.c
+++ b/src/libtracker-miner/tracker-miner-manager.c
@@ -895,6 +895,80 @@ tracker_miner_manager_pause (TrackerMinerManager *manager,
}
/**
+ * tracker_miner_manager_pause_for_process:
+ * @manager: a #TrackerMinerManager.
+ * @miner: miner reference
+ * @reason: reason to pause
+ * @cookie: return location for the pause cookie ID
+ *
+ * This function operates exactly the same way as
+ * tracker_miner_manager_pause() with the exception that if the calling
+ * process dies, the pause is resumed. This API is useful for cases
+ * where the calling process has a risk of crashing without resuming
+ * the pause.
+ *
+ * Returns: %TRUE if the miner was paused successfully, otherwise
+ * %FALSE.
+ *
+ * Since: 0.10.15
+ **/
+gboolean
+tracker_miner_manager_pause_for_process (TrackerMinerManager *manager,
+ const gchar *miner,
+ const gchar *reason,
+ guint32 *cookie)
+{
+ GDBusProxy *proxy;
+ const gchar *app_name;
+ GError *error = NULL;
+ GVariant *v;
+
+ g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
+ g_return_val_if_fail (miner != NULL, FALSE);
+ g_return_val_if_fail (reason != NULL, FALSE);
+
+ proxy = find_miner_proxy (manager, miner, TRUE);
+
+ if (!proxy) {
+ g_critical ("No D-Bus proxy found for miner '%s'", miner);
+ return FALSE;
+ }
+
+ /* Find a reasonable app name */
+ app_name = g_get_application_name ();
+
+ if (!app_name) {
+ app_name = g_get_prgname ();
+ }
+
+ if (!app_name) {
+ app_name = "TrackerMinerManager client";
+ }
+
+ v = g_dbus_proxy_call_sync (proxy,
+ "PauseForProcess",
+ g_variant_new ("(ss)", app_name, reason),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (error) {
+ g_critical ("Could not pause miner '%s': %s", miner, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ if (cookie) {
+ g_variant_get (v, "(i)", cookie);
+ }
+
+ g_variant_unref (v);
+
+ return TRUE;
+}
+
+/**
* tracker_miner_manager_resume:
* @manager: a #TrackerMinerManager
* @miner: miner reference
diff --git a/src/libtracker-miner/tracker-miner-manager.h b/src/libtracker-miner/tracker-miner-manager.h
index ea3e3e6..83cd3b9 100644
--- a/src/libtracker-miner/tracker-miner-manager.h
+++ b/src/libtracker-miner/tracker-miner-manager.h
@@ -106,6 +106,10 @@ gboolean tracker_miner_manager_pause (TrackerMinerManag
const gchar *miner,
const gchar *reason,
guint32 *cookie);
+gboolean tracker_miner_manager_pause_for_process (TrackerMinerManager *manager,
+ const gchar *miner,
+ const gchar *reason,
+ guint32 *cookie);
gboolean tracker_miner_manager_resume (TrackerMinerManager *manager,
const gchar *miner,
guint32 cookie);
diff --git a/src/libtracker-miner/tracker-miner-object.c b/src/libtracker-miner/tracker-miner-object.c
index e56d55e..58ab05e 100644
--- a/src/libtracker-miner/tracker-miner-object.c
+++ b/src/libtracker-miner/tracker-miner-object.c
@@ -83,6 +83,11 @@ static const gchar introspection_xml[] =
" <arg type='s' name='reason' direction='in' />"
" <arg type='i' name='cookie' direction='out' />"
" </method>"
+ " <method name='PauseForProcess'>"
+ " <arg type='s' name='application' direction='in' />"
+ " <arg type='s' name='reason' direction='in' />"
+ " <arg type='i' name='cookie' direction='out' />"
+ " </method>"
" <method name='Resume'>"
" <arg type='i' name='cookie' direction='in' />"
" </method>"
@@ -121,6 +126,8 @@ typedef struct {
gint cookie;
gchar *application;
gchar *reason;
+ gchar *watch_name;
+ guint watch_name_id;
} PauseData;
enum {
@@ -158,7 +165,9 @@ static gboolean miner_initable_init (GInitable *initable
GError **error);
static void pause_data_destroy (gpointer data);
static PauseData *pause_data_new (const gchar *application,
- const gchar *reason);
+ const gchar *reason,
+ const gchar *watch_name,
+ guint watch_name_id);
static void handle_method_call (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
@@ -617,7 +626,9 @@ miner_get_property (GObject *object,
static PauseData *
pause_data_new (const gchar *application,
- const gchar *reason)
+ const gchar *reason,
+ const gchar *watch_name,
+ guint watch_name_id)
{
PauseData *data;
static gint cookie = 1;
@@ -627,6 +638,8 @@ pause_data_new (const gchar *application,
data->cookie = cookie++;
data->application = g_strdup (application);
data->reason = g_strdup (reason);
+ data->watch_name = g_strdup (watch_name);
+ data->watch_name_id = watch_name_id;
return data;
}
@@ -638,6 +651,12 @@ pause_data_destroy (gpointer data)
pd = data;
+ if (pd->watch_name_id) {
+ g_bus_unwatch_name (pd->watch_name_id);
+ }
+
+ g_free (pd->watch_name);
+
g_free (pd->reason);
g_free (pd->application);
@@ -790,15 +809,58 @@ tracker_miner_get_n_pause_reasons (TrackerMiner *miner)
return g_hash_table_size (miner->priv->pauses);
}
+static void
+pause_process_disappeared_cb (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ TrackerMiner *miner;
+ PauseData *pd = NULL;
+ GError *error = NULL;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ miner = user_data;
+
+ g_message ("Process with name:'%s' has disappeared", name);
+
+ g_hash_table_iter_init (&iter, miner->priv->pauses);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ PauseData *pd_iter = value;
+
+ if (g_strcmp0 (name, pd_iter->watch_name) == 0) {
+ pd = pd_iter;
+ break;
+ }
+ }
+
+ if (!pd) {
+ g_critical ("Could not find PauseData for process with name:'%s'", name);
+ return;
+ }
+
+ /* Resume */
+ g_message ("Resuming pause associated with process");
+
+ tracker_miner_resume (miner, pd->cookie, &error);
+
+ if (error) {
+ g_warning ("Could not resume miner, %s", error->message);
+ g_error_free (error);
+ }
+}
+
static gint
-tracker_miner_pause_internal (TrackerMiner *miner,
- const gchar *application,
- const gchar *reason,
- GError **error)
+miner_pause_internal (TrackerMiner *miner,
+ const gchar *application,
+ const gchar *reason,
+ const gchar *calling_name,
+ GError **error)
{
PauseData *pd;
GHashTableIter iter;
gpointer key, value;
+ guint watch_name_id = 0;
/* Check this is not a duplicate pause */
g_hash_table_iter_init (&iter, miner->priv->pauses);
@@ -814,7 +876,18 @@ tracker_miner_pause_internal (TrackerMiner *miner,
}
}
- pd = pause_data_new (application, reason);
+ if (calling_name) {
+ g_message ("Watching process with name:'%s'", calling_name);
+ watch_name_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
+ calling_name,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ NULL,
+ pause_process_disappeared_cb,
+ miner,
+ NULL);
+ }
+
+ pd = pause_data_new (application, reason, calling_name, watch_name_id);
g_hash_table_insert (miner->priv->pauses,
GINT_TO_POINTER (pd->cookie),
@@ -869,7 +942,7 @@ tracker_miner_pause (TrackerMiner *miner,
application = miner->priv->name;
}
- return tracker_miner_pause_internal (miner, application, reason, error);
+ return miner_pause_internal (miner, application, reason, NULL, error);
}
/**
@@ -1090,7 +1163,48 @@ handle_method_call_pause (TrackerMiner *miner,
application,
reason);
- cookie = tracker_miner_pause_internal (miner, application, reason, &local_error);
+ cookie = miner_pause_internal (miner, application, reason, NULL, &local_error);
+ if (cookie == -1) {
+ tracker_dbus_request_end (request, local_error);
+
+ g_dbus_method_invocation_return_gerror (invocation, local_error);
+
+ g_error_free (local_error);
+
+ return;
+ }
+
+ tracker_dbus_request_end (request, NULL);
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(i)", cookie));
+}
+
+static void
+handle_method_call_pause_for_process (TrackerMiner *miner,
+ GDBusMethodInvocation *invocation,
+ GVariant *parameters)
+{
+ GError *local_error = NULL;
+ gint cookie;
+ const gchar *application = NULL, *reason = NULL;
+ TrackerDBusRequest *request;
+
+ g_variant_get (parameters, "(&s&s)", &application, &reason);
+
+ tracker_gdbus_async_return_if_fail (application != NULL, invocation);
+ tracker_gdbus_async_return_if_fail (reason != NULL, invocation);
+
+ request = tracker_g_dbus_request_begin (invocation,
+ "%s(application:'%s', reason:'%s')",
+ __PRETTY_FUNCTION__,
+ application,
+ reason);
+
+ cookie = miner_pause_internal (miner,
+ application,
+ reason,
+ g_dbus_method_invocation_get_sender (invocation),
+ &local_error);
if (cookie == -1) {
tracker_dbus_request_end (request, local_error);
@@ -1207,23 +1321,19 @@ handle_method_call (GDBusConnection *connection,
if (g_strcmp0 (method_name, "IgnoreNextUpdate") == 0) {
handle_method_call_ignore_next_update (miner, invocation, parameters);
- } else
- if (g_strcmp0 (method_name, "Resume") == 0) {
+ } else if (g_strcmp0 (method_name, "Resume") == 0) {
handle_method_call_resume (miner, invocation, parameters);
- } else
- if (g_strcmp0 (method_name, "Pause") == 0) {
+ } else if (g_strcmp0 (method_name, "Pause") == 0) {
handle_method_call_pause (miner, invocation, parameters);
- } else
- if (g_strcmp0 (method_name, "GetPauseDetails") == 0) {
+ } else if (g_strcmp0 (method_name, "PauseForProcess") == 0) {
+ handle_method_call_pause_for_process (miner, invocation, parameters);
+ } else if (g_strcmp0 (method_name, "GetPauseDetails") == 0) {
handle_method_call_get_pause_details (miner, invocation, parameters);
- } else
- if (g_strcmp0 (method_name, "GetRemainingTime") == 0) {
+ } else if (g_strcmp0 (method_name, "GetRemainingTime") == 0) {
handle_method_call_get_remaining_time (miner, invocation, parameters);
- } else
- if (g_strcmp0 (method_name, "GetProgress") == 0) {
+ } else if (g_strcmp0 (method_name, "GetProgress") == 0) {
handle_method_call_get_progress (miner, invocation, parameters);
- } else
- if (g_strcmp0 (method_name, "GetStatus") == 0) {
+ } else if (g_strcmp0 (method_name, "GetStatus") == 0) {
handle_method_call_get_status (miner, invocation, parameters);
} else {
g_assert_not_reached ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]