summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--inc/abrtlib.h11
-rw-r--r--lib/Utils/abrt_dbus.cpp202
-rw-r--r--lib/Utils/abrt_dbus.h10
-rw-r--r--lib/Utils/logging.cpp2
-rw-r--r--src/Applet/Makefile.am6
-rw-r--r--src/Daemon/CommLayerServerDBus.cpp183
-rw-r--r--src/Daemon/Daemon.cpp1
-rw-r--r--src/Daemon/Daemon.h10
8 files changed, 230 insertions, 195 deletions
diff --git a/inc/abrtlib.h b/inc/abrtlib.h
index 1affdf91..c99f4b7e 100644
--- a/inc/abrtlib.h
+++ b/inc/abrtlib.h
@@ -83,6 +83,17 @@ extern void verror_msg(const char *s, va_list p, const char *strerr);
#undef log
#define log(...) error_msg(__VA_ARGS__)
+/* Verbosity level */
+extern int g_verbose;
+/* VERB1 log("what you sometimes want to see, even on a production box") */
+#define VERB1 if (g_verbose >= 1)
+/* VERB2 log("debug message, not going into insanely small details") */
+#define VERB2 if (g_verbose >= 2)
+/* VERB3 log("lots and lots of details") */
+#define VERB3 if (g_verbose >= 3)
+/* there is no level > 3 */
+
+
void* xmalloc(size_t size);
void* xrealloc(void *ptr, size_t size);
void* xzalloc(size_t size);
diff --git a/lib/Utils/abrt_dbus.cpp b/lib/Utils/abrt_dbus.cpp
index 3d868b9d..37d6d3e6 100644
--- a/lib/Utils/abrt_dbus.cpp
+++ b/lib/Utils/abrt_dbus.cpp
@@ -1,9 +1,11 @@
#include <dbus/dbus.h>
+#include <glib.h>
#include "abrtlib.h"
#include "abrt_dbus.h"
DBusConnection* g_dbus_conn;
+
/*
* Helpers for building DBus messages
*/
@@ -40,6 +42,7 @@ void store_string(DBusMessageIter* iter, const char* val)
die_out_of_memory();
}
+
/*
* Helpers for parsing DBus messages
*/
@@ -110,3 +113,202 @@ int load_charp(DBusMessageIter* iter, const char*& val)
//log("load_charp:'%s'", val);
return dbus_message_iter_next(iter);
}
+
+
+/*
+ * Glib integration machinery
+ */
+
+/* Callback: "glib says dbus fd is active" */
+static gboolean handle_dbus_fd(GIOChannel *gio, GIOCondition condition, gpointer data)
+{
+ DBusWatch *watch = (DBusWatch*)data;
+
+ VERB3 log("%s(gio, condition:%x [bits:IN/PRI/OUT/ERR/HUP...], data)", __func__, int(condition));
+
+ /* Notify the D-Bus library when a previously-added watch
+ * is ready for reading or writing, or has an exception such as a hangup.
+ */
+ int glib_flags = int(condition);
+ int dbus_flags = 0;
+ if (glib_flags & G_IO_IN) dbus_flags |= DBUS_WATCH_READABLE;
+ if (glib_flags & G_IO_OUT) dbus_flags |= DBUS_WATCH_WRITABLE;
+ if (glib_flags & G_IO_ERR) dbus_flags |= DBUS_WATCH_ERROR;
+ if (glib_flags & G_IO_HUP) dbus_flags |= DBUS_WATCH_HANGUP;
+ /*
+ * TODO:
+ * If dbus_watch_handle returns FALSE, then the file descriptor
+ * may still be ready for reading or writing, but more memory
+ * is needed in order to do the reading or writing. If you ignore
+ * the FALSE return, your application may spin in a busy loop
+ * on the file descriptor until memory becomes available,
+ * but nothing more catastrophic should happen.
+ */
+ dbus_watch_handle(watch, dbus_flags);
+
+ while (dbus_connection_dispatch(g_dbus_conn) == DBUS_DISPATCH_DATA_REMAINS)
+ VERB3 log("%s: more data to process, looping", __func__);
+ return TRUE; /* "glib, do not remove this even source!" */
+}
+
+struct watch_app_info_t
+{
+ GIOChannel *channel;
+ guint event_source_id;
+ bool watch_enabled;
+};
+/* Callback: "dbus_watch_get_enabled() may return a different value than it did before" */
+static void toggled_watch(DBusWatch *watch, void* data)
+{
+ VERB3 log("%s(watch:%p, data)", __func__, watch);
+
+ watch_app_info_t* app_info = (watch_app_info_t*)dbus_watch_get_data(watch);
+ if (dbus_watch_get_enabled(watch))
+ {
+ if (!app_info->watch_enabled)
+ {
+ app_info->watch_enabled = true;
+ int dbus_flags = dbus_watch_get_flags(watch);
+ int glib_flags = 0;
+ if (dbus_flags & DBUS_WATCH_READABLE)
+ glib_flags |= G_IO_IN;
+ if (dbus_flags & DBUS_WATCH_WRITABLE)
+ glib_flags |= G_IO_OUT;
+ VERB3 log(" adding watch to glib main loop. dbus_flags:%x glib_flags:%x", dbus_flags, glib_flags);
+ app_info->event_source_id = g_io_add_watch(app_info->channel, GIOCondition(glib_flags), handle_dbus_fd, watch);
+ }
+ /* else: it was already enabled */
+ } else {
+ if (app_info->watch_enabled)
+ {
+ app_info->watch_enabled = false;
+ /* does it free the hidden GSource too? */
+ VERB3 log(" removing watch from glib main loop");
+ g_source_remove(app_info->event_source_id);
+ }
+ /* else: it was already disabled */
+ }
+}
+/* Callback: "libdbus needs a new watch to be monitored by the main loop" */
+static dbus_bool_t add_watch(DBusWatch *watch, void* data)
+{
+ VERB3 log("%s(watch:%p, data)", __func__, watch);
+
+ watch_app_info_t* app_info = (watch_app_info_t*)xzalloc(sizeof(*app_info));
+ dbus_watch_set_data(watch, app_info, free);
+
+ int fd = dbus_watch_get_unix_fd(watch);
+ VERB3 log(" dbus_watch_get_unix_fd():%d", fd);
+ app_info->channel = g_io_channel_unix_new(fd);
+ /* _unconditionally_ adding it to event loop would be an error */
+ toggled_watch(watch, data);
+ return TRUE;
+}
+/* Callback: "libdbus no longer needs a watch to be monitored by the main loop" */
+static void remove_watch(DBusWatch *watch, void* data)
+{
+ VERB3 log("%s()", __func__);
+ watch_app_info_t* app_info = (watch_app_info_t*)dbus_watch_get_data(watch);
+ if (app_info->watch_enabled)
+ {
+ app_info->watch_enabled = false;
+ g_source_remove(app_info->event_source_id);
+ }
+ g_io_channel_unref(app_info->channel);
+}
+
+/* Callback: "libdbus needs a new timeout to be monitored by the main loop" */
+static dbus_bool_t add_timeout(DBusTimeout *timeout, void* data)
+{
+ VERB3 log("%s()", __func__);
+ return TRUE;
+}
+/* Callback: "libdbus no longer needs a timeout to be monitored by the main loop" */
+static void remove_timeout(DBusTimeout *timeout, void* data)
+{
+ VERB3 log("%s()", __func__);
+}
+/* Callback: "dbus_timeout_get_enabled() may return a different value than it did before" */
+static void timeout_toggled(DBusTimeout *timeout, void* data)
+{
+//seems to be never called, let's make it noisy
+ error_msg_and_die("%s(): FIXME: some dbus machinery is missing here", __func__);
+}
+
+/* Callback: "DBusObjectPathVTable is unregistered (or its connection is freed)" */
+static void unregister_vtable(DBusConnection *conn, void* data)
+{
+ VERB3 log("%s()", __func__);
+}
+
+/*
+ * Initialization works as follows:
+ *
+ * we have a DBusConnection* (say, obtained with dbus_bus_get)
+ * we call dbus_connection_set_watch_functions
+ * libdbus calls back add_watch(watch:0x2341090, data), this watch is for writing
+ * we call toggled_watch, but it finds that watch is not to be enabled yet
+ * libdbus calls back add_watch(watch:0x23410e0, data), this watch is for reading
+ * we call toggled_watch, it adds watch's fd to glib main loop with POLLIN
+ * (note: these watches are different objects, but they have the same fd)
+ * we call dbus_connection_set_timeout_functions
+ * we call dbus_connection_register_object_path
+ *
+ * Note: if user will later call dbus_bus_request_name(conn, ...):
+ * libdbus calls back add_timeout()
+ * libdbus calls back remove_timeout()
+ * note - no callback to timeout_toggled()!
+ * (therefore there is no code yet in timeout_toggled (see above), it's not used)
+ */
+void attach_dbus_conn_to_glib_main_loop(DBusConnection* conn,
+ const char* object_path,
+ DBusHandlerResult (*message_received_func)(DBusConnection *conn, DBusMessage *msg, void* data)
+) {
+//do we need this? why?
+//log("dbus_connection_set_dispatch_status_function");
+// dbus_connection_set_dispatch_status_function(conn,
+// dispatch, /* void dispatch(DBusConnection *conn, DBusDispatchStatus new_status, void* data) */
+// NULL, /* data */
+// NULL /* free_data_function */
+// )
+ VERB3 log("dbus_connection_set_watch_functions");
+ if (!dbus_connection_set_watch_functions(conn,
+ add_watch,
+ remove_watch,
+ toggled_watch,
+ NULL, /* data */
+ NULL /* free_data_function */
+ )
+ ) {
+ die_out_of_memory();
+ }
+ VERB3 log("dbus_connection_set_timeout_functions");
+ if (!dbus_connection_set_timeout_functions(conn,
+ add_timeout,
+ remove_timeout,
+ timeout_toggled,
+ NULL, /* data */
+ NULL /* free_data_function */
+ )
+ ) {
+ die_out_of_memory();
+ }
+
+ if (object_path && message_received_func)
+ {
+ /* Table */
+ const DBusObjectPathVTable vtable = {
+ /* .unregister_function = */ unregister_vtable,
+ /* .message_function = */ message_received_func,
+ };
+ VERB3 log("dbus_connection_register_object_path");
+ if (!dbus_connection_register_object_path(conn,
+ object_path,
+ &vtable,
+ NULL /* data */
+ )
+ ) {
+ die_out_of_memory();
+ }
+ }
+}
diff --git a/lib/Utils/abrt_dbus.h b/lib/Utils/abrt_dbus.h
index e2bf9fbf..731f1c10 100644
--- a/lib/Utils/abrt_dbus.h
+++ b/lib/Utils/abrt_dbus.h
@@ -6,6 +6,16 @@
extern DBusConnection* g_dbus_conn;
/*
+ * Glib integration machinery
+ */
+void attach_dbus_conn_to_glib_main_loop(DBusConnection* conn,
+ const char* object_path_to_register = NULL, /* NULL if you are just a client */
+ /* makes sense only if you use object_path_to_register: */
+ DBusHandlerResult (*message_received_func)(DBusConnection *conn, DBusMessage *msg, void* data) = NULL
+);
+
+
+/*
* Helpers for building DBus messages
*/
diff --git a/lib/Utils/logging.cpp b/lib/Utils/logging.cpp
index d79ded5d..f70d23f3 100644
--- a/lib/Utils/logging.cpp
+++ b/lib/Utils/logging.cpp
@@ -8,6 +8,8 @@
int xfunc_error_retval = EXIT_FAILURE;
+int g_verbose;
+
void xfunc_die(void)
{
exit(xfunc_error_retval);
diff --git a/src/Applet/Makefile.am b/src/Applet/Makefile.am
index accca397..67c17766 100644
--- a/src/Applet/Makefile.am
+++ b/src/Applet/Makefile.am
@@ -23,13 +23,13 @@ abrt_applet_CPPFLAGS = \
# $(DBUS_CFLAGS)
# $(DBUS_GLIB_CFLAGS)
abrt_applet_LDADD = \
- ../../lib/Utils/libABRTUtils.la \
-lglib-2.0 \
-lgthread-2.0 \
- $(DL_LIBS) \
- $(GTK_LIBS) \
$(DBUSCPP_LIBS) \
$(LIBNOTIFY_LIBS)
+# ../../lib/Utils/libABRTUtils.la
+# $(DL_LIBS)
+# $(GTK_LIBS)
EXTRA_DIST = abrt-applet.desktop popup.GtkBuilder
diff --git a/src/Daemon/CommLayerServerDBus.cpp b/src/Daemon/CommLayerServerDBus.cpp
index 2f88a72b..08cd3d5e 100644
--- a/src/Daemon/CommLayerServerDBus.cpp
+++ b/src/Daemon/CommLayerServerDBus.cpp
@@ -1,4 +1,3 @@
-//#include <iostream>
#include <dbus/dbus.h>
#include "abrtlib.h"
#include "abrt_dbus.h"
@@ -430,121 +429,6 @@ static int handle_SetSettings(DBusMessage* call, DBusMessage* reply)
* Glib integration machinery
*/
-/* Callback: "glib says dbus fd is active" */
-static gboolean handle_dbus(GIOChannel *gio, GIOCondition condition, gpointer data)
-{
- DBusWatch *watch = (DBusWatch*)data;
-
- VERB3 log("%s(gio, condition:%x [bits:IN/PRI/OUT/ERR/HUP...], data)", __func__, int(condition));
-
- /* Notify the D-Bus library when a previously-added watch
- * is ready for reading or writing, or has an exception such as a hangup.
- */
- int glib_flags = int(condition);
- int dbus_flags = 0;
- if (glib_flags & G_IO_IN) dbus_flags |= DBUS_WATCH_READABLE;
- if (glib_flags & G_IO_OUT) dbus_flags |= DBUS_WATCH_WRITABLE;
- if (glib_flags & G_IO_ERR) dbus_flags |= DBUS_WATCH_ERROR;
- if (glib_flags & G_IO_HUP) dbus_flags |= DBUS_WATCH_HANGUP;
- /*
- * TODO:
- * If dbus_watch_handle returns FALSE, then the file descriptor
- * may still be ready for reading or writing, but more memory
- * is needed in order to do the reading or writing. If you ignore
- * the FALSE return, your application may spin in a busy loop
- * on the file descriptor until memory becomes available,
- * but nothing more catastrophic should happen.
- */
- dbus_watch_handle(watch, dbus_flags);
-
- while (dbus_connection_dispatch(g_dbus_conn) == DBUS_DISPATCH_DATA_REMAINS)
- VERB3 log("%s: more data to process, looping", __func__);
- return TRUE; /* "glib, do not remove this even source!" */
-}
-struct watch_app_info_t
-{
- GIOChannel *channel;
- guint event_source_id;
- bool watch_enabled;
-};
-/* Callback: "dbus_watch_get_enabled() may return a different value than it did before" */
-static void toggled_watch(DBusWatch *watch, void* data)
-{
- VERB3 log("%s(watch:%p, data)", __func__, watch);
-
- watch_app_info_t* app_info = (watch_app_info_t*)dbus_watch_get_data(watch);
- if (dbus_watch_get_enabled(watch))
- {
- if (!app_info->watch_enabled)
- {
- app_info->watch_enabled = true;
- int dbus_flags = dbus_watch_get_flags(watch);
- int glib_flags = 0;
- if (dbus_flags & DBUS_WATCH_READABLE)
- glib_flags |= G_IO_IN;
- if (dbus_flags & DBUS_WATCH_WRITABLE)
- glib_flags |= G_IO_OUT;
- VERB3 log(" adding watch to glib main loop. dbus_flags:%x glib_flags:%x", dbus_flags, glib_flags);
- app_info->event_source_id = g_io_add_watch(app_info->channel, GIOCondition(glib_flags), handle_dbus, watch);
- }
- /* else: it was already enabled */
- } else {
- if (app_info->watch_enabled)
- {
- app_info->watch_enabled = false;
- /* does it free the hidden GSource too? */
- VERB3 log(" removing watch from glib main loop");
- g_source_remove(app_info->event_source_id);
- }
- /* else: it was already disabled */
- }
-}
-/* Callback: "libdbus needs a new watch to be monitored by the main loop" */
-static dbus_bool_t add_watch(DBusWatch *watch, void* data)
-{
- VERB3 log("%s(watch:%p, data)", __func__, watch);
-
- watch_app_info_t* app_info = (watch_app_info_t*)xzalloc(sizeof(*app_info));
- dbus_watch_set_data(watch, app_info, free);
-
- int fd = dbus_watch_get_unix_fd(watch);
- VERB3 log(" dbus_watch_get_unix_fd():%d", fd);
- app_info->channel = g_io_channel_unix_new(fd);
- /* _unconditionally_ adding it to event loop would be an error */
- toggled_watch(watch, data);
- return TRUE;
-}
-/* Callback: "libdbus no longer needs a watch to be monitored by the main loop" */
-static void remove_watch(DBusWatch *watch, void* data)
-{
- VERB3 log("%s()", __func__);
- watch_app_info_t* app_info = (watch_app_info_t*)dbus_watch_get_data(watch);
- if (app_info->watch_enabled)
- {
- app_info->watch_enabled = false;
- g_source_remove(app_info->event_source_id);
- }
- g_io_channel_unref(app_info->channel);
-}
-
-/* Callback: "libdbus needs a new timeout to be monitored by the main loop" */
-static dbus_bool_t add_timeout(DBusTimeout *timeout, void* data)
-{
- VERB3 log("%s()", __func__);
- return TRUE;
-}
-/* Callback: "libdbus no longer needs a timeout to be monitored by the main loop" */
-static void remove_timeout(DBusTimeout *timeout, void* data)
-{
- VERB3 log("%s()", __func__);
-}
-/* Callback: "dbus_timeout_get_enabled() may return a different value than it did before" */
-static void timeout_toggled(DBusTimeout *timeout, void* data)
-{
-//seems to be never called, let's make it noisy
- log("%s()", __func__);
-}
-
/* Callback: "a message is received to a registered object path" */
static DBusHandlerResult message_received(DBusConnection *conn, DBusMessage *msg, void* data)
{
@@ -603,16 +487,6 @@ static DBusHandlerResult message_received(DBusConnection *conn, DBusMessage *msg
return DBUS_HANDLER_RESULT_HANDLED;
}
-/* Callback: "DBusObjectPathVTable is unregistered (or its connection is freed)" */
-static void unregister_vtable(DBusConnection *conn, void* data)
-{
- VERB3 log("%s()", __func__);
-}
-/* Table */
-static const DBusObjectPathVTable vtable = {
- /* .unregister_function = */ unregister_vtable,
- /* .message_function = */ message_received,
-};
static void handle_dbus_err(bool error_flag, DBusError *err)
{
@@ -630,23 +504,6 @@ static void handle_dbus_err(bool error_flag, DBusError *err)
CC_DBUS_NAME);
}
-/*
- * Initialization works as follows:
- *
- * we call dbus_bus_get
- * we call dbus_connection_set_watch_functions
- * libdbus calls back add_watch(watch:0x2341090, data), this watch is for writing
- * we call toggled_watch, but it finds that watch is not to be enabled yet
- * libdbus calls back add_watch(watch:0x23410e0, data), this watch is for reading
- * we call toggled_watch, it adds watch's fd to glib main loop with POLLIN
- * (note: these watches are different objects, but they have the same fd)
- * we call dbus_connection_set_timeout_functions
- * we call dbus_connection_register_object_path
- * we call dbus_bus_request_name
- * libdbus calls back add_timeout()
- * libdbus calls back remove_timeout()
- * (therefore there is no code yet in timeout_toggled (see above), it's not used)
- */
CCommLayerServerDBus::CCommLayerServerDBus()
{
DBusConnection* conn;
@@ -657,44 +514,8 @@ CCommLayerServerDBus::CCommLayerServerDBus()
g_dbus_conn = conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
handle_dbus_err(conn == NULL, &err);
-//do we need this? why?
-//log("dbus_connection_set_dispatch_status_function");
-// dbus_connection_set_dispatch_status_function(conn,
-// dispatch, /* void dispatch(DBusConnection *conn, DBusDispatchStatus new_status, void* data) */
-// NULL, /* data */
-// NULL /* free_data_function */
-// )
- VERB3 log("dbus_connection_set_watch_functions");
- if (!dbus_connection_set_watch_functions(conn,
- add_watch,
- remove_watch,
- toggled_watch,
- NULL, /* data */
- NULL /* free_data_function */
- )
- ) {
- die_out_of_memory();
- }
- VERB3 log("dbus_connection_set_timeout_functions");
- if (!dbus_connection_set_timeout_functions(conn,
- add_timeout,
- remove_timeout,
- timeout_toggled,
- NULL, /* data */
- NULL /* free_data_function */
- )
- ) {
- die_out_of_memory();
- }
- VERB3 log("dbus_connection_register_object_path");
- if (!dbus_connection_register_object_path(conn,
- "/com/redhat/abrt",
- &vtable,
- NULL /* data */
- )
- ) {
- die_out_of_memory();
- }
+ attach_dbus_conn_to_glib_main_loop(conn, "/com/redhat/abrt", message_received);
+
VERB3 log("dbus_bus_request_name");
int rc = dbus_bus_request_name(conn, CC_DBUS_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
handle_dbus_err(rc < 0, &err);
diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp
index 5a5dfeb2..780210cb 100644
--- a/src/Daemon/Daemon.cpp
+++ b/src/Daemon/Daemon.cpp
@@ -112,7 +112,6 @@ typedef struct cron_callback_data_t
static uint8_t s_sig_caught;
static GMainLoop* g_pMainloop;
-int g_verbose;
CCommLayerServer* g_pCommLayer;
pthread_mutex_t g_pJobsMutex;
diff --git a/src/Daemon/Daemon.h b/src/Daemon/Daemon.h
index e03d983a..c9a653ac 100644
--- a/src/Daemon/Daemon.h
+++ b/src/Daemon/Daemon.h
@@ -28,16 +28,6 @@ class CCrashWatcher;
class CCommLayerServer;
class CPluginManager;
-/* Verbosity level */
-extern int g_verbose;
-/* VERB1 log("what you sometimes want to see, even on a production box") */
-#define VERB1 if (g_verbose >= 1)
-/* VERB2 log("debug message, not going into insanely small details") */
-#define VERB2 if (g_verbose >= 2)
-/* VERB3 log("lots and lots of details") */
-#define VERB3 if (g_verbose >= 3)
-/* there is no level > 3 */
-
/* Used for sending dbus signals */
extern CCommLayerServer *g_pCommLayer;