summaryrefslogtreecommitdiffstats
path: root/src/service-dbus/util/serviceutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service-dbus/util/serviceutil.c')
-rw-r--r--src/service-dbus/util/serviceutil.c193
1 files changed, 192 insertions, 1 deletions
diff --git a/src/service-dbus/util/serviceutil.c b/src/service-dbus/util/serviceutil.c
index 50b18b9..eed0ad8 100644
--- a/src/service-dbus/util/serviceutil.c
+++ b/src/service-dbus/util/serviceutil.c
@@ -26,7 +26,6 @@
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
-#include <gio/gio.h>
#include "serviceutil.h"
@@ -346,3 +345,195 @@ unsigned int service_operation(
g_object_unref(manager_proxy);
return 0;
}
+
+/* Indications */
+
+pthread_mutex_t m;
+pthread_cond_t c;
+
+void *loop_thread(
+ void *arg)
+{
+ ServiceIndication *si = (ServiceIndication *) arg;
+
+ lmi_debug("loop_thread enter");
+
+ g_main_loop_run(si->loop);
+
+ lmi_debug("loop_thread exit");
+
+ return NULL;
+}
+
+static void on_signal(
+ GDBusProxy *proxy,
+ gchar *sender_name,
+ gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ lmi_debug("on_signal enter, object_path: %s", g_dbus_proxy_get_object_path(proxy));
+
+ pthread_mutex_lock(&m);
+ pthread_cond_signal(&c);
+ pthread_mutex_unlock(&m);
+
+ lmi_debug("on_signal exit");
+}
+
+int ind_init(ServiceIndication *si, char *output, int output_len)
+{
+ GVariant *result = NULL;
+ GError *error = NULL;
+ gchar *tmps = NULL;
+ int i = 0;
+
+ lmi_debug("ind_init enter");
+
+ si->context = g_main_context_new();
+ g_main_context_push_thread_default(si->context);
+
+ si->loop = NULL;
+
+ si->slist = service_find_all(output, output_len);
+ if (si->slist == NULL) {
+ g_main_context_unref(si->context);
+ return -1;
+ }
+
+ si->manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, MANAGER_NAME, MANAGER_OP, MANAGER_INTERFACE, NULL, &error);
+ if (!si->manager_proxy) {
+ strncpy(output, error->message, output_len);
+ g_error_free(error);
+ g_main_context_unref(si->context);
+ service_free_slist(si->slist);
+ return -1;
+ }
+
+ si->signal_proxy = malloc(si->slist->cnt * sizeof(GDBusProxy *));
+ if (!si->signal_proxy) {
+ strncpy(output, "Insufficient memory", output_len);
+ g_main_context_unref(si->context);
+ service_free_slist(si->slist);
+ return -1;
+ }
+
+ for (i = 0; i < si->slist->cnt; i++) {
+ result = g_dbus_proxy_call_sync(si->manager_proxy, "LoadUnit", g_variant_new("(s)", si->slist->name[i]),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) {
+ strncpy(output, error->message, output_len);
+ g_error_free(error);
+ ind_destroy(si);
+ return -1;
+ }
+ g_variant_get(result, "(&o)", &tmps);
+
+ error = NULL;
+ si->signal_proxy[i] = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, MANAGER_NAME, tmps, PROPERTY_INTERFACE, NULL, &error);
+ g_variant_unref(result);
+ if (si->signal_proxy[i] == NULL)
+ {
+ strncpy(output, error->message, output_len);
+ g_error_free(error);
+ ind_destroy(si);
+ return -1;
+ }
+ g_signal_connect(si->signal_proxy[i], "g-signal", G_CALLBACK(on_signal), NULL);
+ }
+
+ error = NULL;
+ g_dbus_proxy_call_sync(si->manager_proxy, "Subscribe", NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) {
+ strncpy(output, error->message, output_len);
+ g_error_free(error);
+ ind_destroy(si);
+ return -1;
+ }
+
+ g_main_context_pop_thread_default(si->context);
+
+ si->loop = g_main_loop_new(si->context, FALSE);
+
+ if (pthread_create(&si->p, NULL, loop_thread, si) != 0) {
+ ind_destroy(si);
+ return -1;
+ }
+
+ if (pthread_mutex_init(&m, NULL) != 0) {
+ strncpy(output, "pthread_mutex_init error", output_len);
+ return -1;
+ }
+ if (pthread_cond_init(&c, NULL) != 0) {
+ strncpy(output, "pthread_cond_init error", output_len);
+ return -1;
+ }
+
+ lmi_debug("ind_init exit");
+
+ return 0;
+}
+
+bool ind_watcher(
+ void **data)
+{
+ lmi_debug("ind_watcher enter");
+
+ pthread_mutex_lock(&m);
+ pthread_cond_wait(&c, &m);
+ pthread_mutex_unlock(&m);
+
+ lmi_debug("ind_watcher exit");
+
+ return true;
+}
+
+void ind_destroy(ServiceIndication *si)
+{
+ int i;
+ GError *error = NULL;
+
+ lmi_debug("ind_destroy enter");
+
+ if (si->loop) {
+ g_main_loop_quit(si->loop);
+ if (pthread_join(si->p, NULL) != 0) {
+ lmi_debug("pthread_join error");
+ }
+ g_main_loop_unref(si->loop);
+ }
+
+ if (pthread_cond_destroy(&c) != 0) {
+ lmi_debug("pthread_cond_destroy error");
+ }
+ if (pthread_mutex_destroy(&m) != 0) {
+ lmi_debug("pthread_mutex_destroy error");
+ }
+
+ g_main_context_unref(si->context);
+
+ for (i = 0; i < si->slist->cnt; i++) {
+ if (si->signal_proxy[i]) {
+ g_object_unref(si->signal_proxy[i]);
+ }
+ }
+ free(si->signal_proxy);
+
+ g_dbus_proxy_call_sync(si->manager_proxy, "Unsubscribe", NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) {
+ lmi_debug("Unsubscribe error: %s", error->message);
+ g_error_free(error);
+ }
+
+ g_object_unref(si->manager_proxy);
+
+ service_free_slist(si->slist);
+
+ lmi_debug("ind_destroy exit");
+
+ return;
+}