[gvfs] hal: Bring gvfsdbusutils.c back and make it private



commit 58ba8d331b4f1ae071f3fe016ad934cbfc836308
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Fri Sep 14 15:41:54 2012 +0200

    hal: Bring gvfsdbusutils.c back and make it private
    
    ... in order to be able to compile.
    
    gvfsdbusutils.c was removed by commit 288e9153f1f though hal still
    needs it for compilation. Let's make it private to hal and strip
    unnecessary functions.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=683367

 monitor/hal/Makefile.am     |    3 +
 monitor/hal/gvfsdbusutils.c |  538 +++++++++++++++++++++++++++++++++++++++++++
 monitor/hal/gvfsdbusutils.h |   42 ++++
 3 files changed, 583 insertions(+), 0 deletions(-)
---
diff --git a/monitor/hal/Makefile.am b/monitor/hal/Makefile.am
index 8ccced6..002cfca 100644
--- a/monitor/hal/Makefile.am
+++ b/monitor/hal/Makefile.am
@@ -23,6 +23,7 @@ gvfs_hal_volume_monitor_SOURCES =			\
 	ghalvolume.c		ghalvolume.h		\
 	ghalmount.c		ghalmount.h		\
 	ghalvolumemonitor.c	ghalvolumemonitor.h	\
+	gvfsdbusutils.c		gvfsdbusutils.h		\
 	$(NULL)
 
 gvfs_hal_volume_monitor_CFLAGS =		\
@@ -30,6 +31,7 @@ gvfs_hal_volume_monitor_CFLAGS =		\
 	-I$(top_srcdir)/common                  \
 	-I$(top_srcdir)/monitor/proxy           \
 	$(GLIB_CFLAGS)                          \
+	$(DBUS_CFLAGS)                          \
 	$(HAL_CFLAGS)                           \
 	-DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\"	\
 	-DGVFS_LOCALEDIR=\""$(localedir)"\"	\
@@ -40,6 +42,7 @@ gvfs_hal_volume_monitor_LDFLAGS =	\
 
 gvfs_hal_volume_monitor_LDADD  =		     			      \
 	$(GLIB_LIBS)                                 			      \
+	$(DBUS_LIBS)                                 			      \
 	$(HAL_LIBS)                                  			      \
 	$(top_builddir)/common/libgvfscommon.la 			      \
 	$(top_builddir)/common/libgvfscommon-monitor.la			      \
diff --git a/monitor/hal/gvfsdbusutils.c b/monitor/hal/gvfsdbusutils.c
new file mode 100644
index 0000000..08a6205
--- /dev/null
+++ b/monitor/hal/gvfsdbusutils.c
@@ -0,0 +1,538 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib/gi18n-lib.h>
+#include <gvfsdbusutils.h>
+#include <gio/gio.h>
+
+static void
+_g_dbus_oom (void)
+{
+  g_error ("DBus failed with out of memory error");
+}
+
+/*************************************************************************
+ *             Helper fd source                                          *
+ ************************************************************************/
+
+typedef struct 
+{
+  GSource source;
+  GPollFD pollfd;
+  GCancellable *cancellable;
+  gulong cancelled_tag;
+} FDSource;
+
+static gboolean 
+fd_source_prepare (GSource  *source,
+		   gint     *timeout)
+{
+  FDSource *fd_source = (FDSource *)source;
+  *timeout = -1;
+  
+  return g_cancellable_is_cancelled (fd_source->cancellable);
+}
+
+static gboolean 
+fd_source_check (GSource  *source)
+{
+  FDSource *fd_source = (FDSource *)source;
+
+  return
+    g_cancellable_is_cancelled  (fd_source->cancellable) ||
+    fd_source->pollfd.revents != 0;
+}
+
+static gboolean
+fd_source_dispatch (GSource     *source,
+		    GSourceFunc  callback,
+		    gpointer     user_data)
+
+{
+  GFDSourceFunc func = (GFDSourceFunc)callback;
+  FDSource *fd_source = (FDSource *)source;
+
+  g_assert (func != NULL);
+
+  return (*func) (user_data, fd_source->pollfd.revents, fd_source->pollfd.fd);
+}
+
+static void 
+fd_source_finalize (GSource *source)
+{
+  FDSource *fd_source = (FDSource *)source;
+
+  if (fd_source->cancelled_tag)
+    g_cancellable_disconnect (fd_source->cancellable,
+			      fd_source->cancelled_tag);
+
+  if (fd_source->cancellable)
+    g_object_unref (fd_source->cancellable);
+}
+
+static GSourceFuncs fd_source_funcs = {
+  fd_source_prepare,
+  fd_source_check,
+  fd_source_dispatch,
+  fd_source_finalize
+};
+
+/* Might be called on another thread */
+static void
+fd_source_cancelled_cb (GCancellable *cancellable,
+			gpointer data)
+{
+  /* Wake up the mainloop in case we're waiting on async calls with FDSource */
+  g_main_context_wakeup (NULL);
+}
+
+/* Two __ to avoid conflict with gio version */
+GSource *
+__g_fd_source_new (int fd,
+		   gushort events,
+		   GCancellable *cancellable)
+{
+  GSource *source;
+  FDSource *fd_source;
+
+  source = g_source_new (&fd_source_funcs, sizeof (FDSource));
+  fd_source = (FDSource *)source;
+
+  if (cancellable)
+    fd_source->cancellable = g_object_ref (cancellable);
+  
+  fd_source->pollfd.fd = fd;
+  fd_source->pollfd.events = events;
+  g_source_add_poll (source, &fd_source->pollfd);
+
+  if (cancellable)
+    fd_source->cancelled_tag =
+      g_cancellable_connect (cancellable,
+			     (GCallback)fd_source_cancelled_cb,
+			     NULL, NULL);
+  
+  return source;
+}
+
+/*************************************************************************
+ *                                                                       *
+ *      dbus mainloop integration for async ops                          *
+ *                                                                       *
+ *************************************************************************/
+
+static gint32 main_integration_data_slot = -1;
+static GOnce once_init_main_integration = G_ONCE_INIT;
+
+/**
+ * A GSource subclass for dispatching DBusConnection messages.
+ * We need this on top of the IO handlers, because sometimes
+ * there are messages to dispatch queued up but no IO pending.
+ * 
+ * The source is owned by the connection (and the main context
+ * while that is alive)
+ */
+typedef struct 
+{
+  GSource source;
+  
+  DBusConnection *connection;
+  GSList *ios;
+  GSList *timeouts;
+} DBusSource;
+
+typedef struct
+{
+  DBusSource *dbus_source;
+  GSource *source;
+  DBusWatch *watch;
+} IOHandler;
+
+typedef struct
+{
+  DBusSource *dbus_source;
+  GSource *source;
+  DBusTimeout *timeout;
+} TimeoutHandler;
+
+static gpointer
+main_integration_init (gpointer arg)
+{
+  if (!dbus_connection_allocate_data_slot (&main_integration_data_slot))
+    g_error ("Unable to allocate data slot");
+
+  return NULL;
+}
+
+static gboolean
+dbus_source_prepare (GSource *source,
+		     gint    *timeout)
+{
+  DBusConnection *connection = ((DBusSource *)source)->connection;
+  
+  *timeout = -1;
+
+  return (dbus_connection_get_dispatch_status (connection) == DBUS_DISPATCH_DATA_REMAINS);  
+}
+
+static gboolean
+dbus_source_check (GSource *source)
+{
+  return FALSE;
+}
+
+static gboolean
+dbus_source_dispatch (GSource     *source,
+		      GSourceFunc  callback,
+		      gpointer     user_data)
+{
+  DBusConnection *connection = ((DBusSource *)source)->connection;
+
+  dbus_connection_ref (connection);
+
+  /* Only dispatch once - we don't want to starve other GSource */
+  dbus_connection_dispatch (connection);
+  
+  dbus_connection_unref (connection);
+
+  return TRUE;
+}
+
+static gboolean
+io_handler_dispatch (gpointer data,
+                     GIOCondition condition,
+                     int fd)
+{
+  IOHandler *handler = data;
+  guint dbus_condition = 0;
+  DBusConnection *connection;
+
+  connection = handler->dbus_source->connection;
+  
+  if (connection)
+    dbus_connection_ref (connection);
+  
+  if (condition & G_IO_IN)
+    dbus_condition |= DBUS_WATCH_READABLE;
+  if (condition & G_IO_OUT)
+    dbus_condition |= DBUS_WATCH_WRITABLE;
+  if (condition & G_IO_ERR)
+    dbus_condition |= DBUS_WATCH_ERROR;
+  if (condition & G_IO_HUP)
+    dbus_condition |= DBUS_WATCH_HANGUP;
+
+  /* Note that we don't touch the handler after this, because
+   * dbus may have disabled the watch and thus killed the
+   * handler.
+   */
+  dbus_watch_handle (handler->watch, dbus_condition);
+  handler = NULL;
+
+  if (connection)
+    dbus_connection_unref (connection);
+  
+  return TRUE;
+}
+
+static void
+io_handler_free (IOHandler *handler)
+{
+  DBusSource *dbus_source;
+  
+  dbus_source = handler->dbus_source;
+  dbus_source->ios = g_slist_remove (dbus_source->ios, handler);
+  
+  g_source_destroy (handler->source);
+  g_source_unref (handler->source);
+  g_free (handler);
+}
+
+static void
+dbus_source_add_watch (DBusSource *dbus_source,
+		       DBusWatch *watch)
+{
+  guint flags;
+  GIOCondition condition;
+  IOHandler *handler;
+  int fd;
+
+  if (!dbus_watch_get_enabled (watch))
+    return;
+  
+  g_assert (dbus_watch_get_data (watch) == NULL);
+  
+  flags = dbus_watch_get_flags (watch);
+
+  condition = G_IO_ERR | G_IO_HUP;
+  if (flags & DBUS_WATCH_READABLE)
+    condition |= G_IO_IN;
+  if (flags & DBUS_WATCH_WRITABLE)
+    condition |= G_IO_OUT;
+
+  handler = g_new0 (IOHandler, 1);
+  handler->dbus_source = dbus_source;
+  handler->watch = watch;
+
+#if (DBUS_MAJOR_VERSION == 1 && DBUS_MINOR_VERSION == 1 && DBUS_MICRO_VERSION >= 1) || (DBUS_MAJOR_VERSION == 1 && DBUS_MINOR_VERSION > 1) || (DBUS_MAJOR_VERSION > 1)
+  fd = dbus_watch_get_unix_fd (watch);
+#else
+  fd = dbus_watch_get_fd (watch);
+#endif
+    
+  handler->source = __g_fd_source_new (fd, condition, NULL);
+  g_source_set_callback (handler->source,
+			 (GSourceFunc) io_handler_dispatch, handler,
+                         NULL);
+  g_source_attach (handler->source, NULL);
+ 
+  dbus_source->ios = g_slist_prepend (dbus_source->ios, handler);
+  dbus_watch_set_data (watch, handler,
+		       (DBusFreeFunction)io_handler_free);
+}
+
+static void
+dbus_source_remove_watch (DBusSource *dbus_source,
+			  DBusWatch *watch)
+{
+  dbus_watch_set_data (watch, NULL, NULL);
+}
+
+static void
+timeout_handler_free (TimeoutHandler *handler)
+{
+  DBusSource *dbus_source;
+
+  dbus_source = handler->dbus_source;
+  dbus_source->timeouts = g_slist_remove (dbus_source->timeouts, handler);
+
+  g_source_destroy (handler->source);
+  g_source_unref (handler->source);
+  g_free (handler);
+}
+
+static gboolean
+timeout_handler_dispatch (gpointer      data)
+{
+  TimeoutHandler *handler = data;
+
+  dbus_timeout_handle (handler->timeout);
+  
+  return TRUE;
+}
+
+static void
+dbus_source_add_timeout (DBusSource *dbus_source,
+			 DBusTimeout *timeout)
+{
+  TimeoutHandler *handler;
+  
+  if (!dbus_timeout_get_enabled (timeout))
+    return;
+  
+  g_assert (dbus_timeout_get_data (timeout) == NULL);
+
+  handler = g_new0 (TimeoutHandler, 1);
+  handler->dbus_source = dbus_source;
+  handler->timeout = timeout;
+
+  handler->source = g_timeout_source_new (dbus_timeout_get_interval (timeout));
+  g_source_set_callback (handler->source,
+			 timeout_handler_dispatch, handler,
+                         NULL);
+  g_source_attach (handler->source, NULL);
+
+  /* handler->source is owned by the context here */
+  dbus_source->timeouts = g_slist_prepend (dbus_source->timeouts, handler);
+
+  dbus_timeout_set_data (timeout, handler,
+			 (DBusFreeFunction)timeout_handler_free);
+}
+
+static void
+dbus_source_remove_timeout (DBusSource *source,
+			    DBusTimeout *timeout)
+{
+  dbus_timeout_set_data (timeout, NULL, NULL);
+}
+
+static dbus_bool_t
+add_watch (DBusWatch *watch,
+	   gpointer   data)
+{
+  DBusSource *dbus_source = data;
+
+  dbus_source_add_watch (dbus_source, watch);
+  
+  return TRUE;
+}
+
+static void
+remove_watch (DBusWatch *watch,
+	      gpointer   data)
+{
+  DBusSource *dbus_source = data;
+
+  dbus_source_remove_watch (dbus_source, watch);
+}
+
+static void
+watch_toggled (DBusWatch *watch,
+               void      *data)
+{
+  /* Because we just exit on OOM, enable/disable is
+   * no different from add/remove */
+  if (dbus_watch_get_enabled (watch))
+    add_watch (watch, data);
+  else
+    remove_watch (watch, data);
+}
+
+static dbus_bool_t
+add_timeout (DBusTimeout *timeout,
+	     void        *data)
+{
+  DBusSource *source = data;
+  
+  if (!dbus_timeout_get_enabled (timeout))
+    return TRUE;
+
+  dbus_source_add_timeout (source, timeout);
+
+  return TRUE;
+}
+
+static void
+remove_timeout (DBusTimeout *timeout,
+		void        *data)
+{
+  DBusSource *source = data;
+
+  dbus_source_remove_timeout (source, timeout);
+}
+
+static void
+timeout_toggled (DBusTimeout *timeout,
+                 void        *data)
+{
+  /* Because we just exit on OOM, enable/disable is
+   * no different from add/remove
+   */
+  if (dbus_timeout_get_enabled (timeout))
+    add_timeout (timeout, data);
+  else
+    remove_timeout (timeout, data);
+}
+
+static void
+wakeup_main (void *data)
+{
+  g_main_context_wakeup (NULL);
+}
+
+static const GSourceFuncs dbus_source_funcs = {
+  dbus_source_prepare,
+  dbus_source_check,
+  dbus_source_dispatch
+};
+
+/* Called when the connection dies or when we're unintegrating from mainloop */
+static void
+dbus_source_free (DBusSource *dbus_source)
+{
+  while (dbus_source->ios)
+    {
+      IOHandler *handler = dbus_source->ios->data;
+      
+      dbus_watch_set_data (handler->watch, NULL, NULL);
+    }
+
+  while (dbus_source->timeouts)
+    {
+      TimeoutHandler *handler = dbus_source->timeouts->data;
+      
+      dbus_timeout_set_data (handler->timeout, NULL, NULL);
+    }
+
+  /* Remove from mainloop */
+  g_source_destroy ((GSource *)dbus_source);
+
+  g_source_unref ((GSource *)dbus_source);
+}
+
+void
+_g_dbus_connection_integrate_with_main  (DBusConnection *connection)
+{
+  DBusSource *dbus_source;
+
+  g_once (&once_init_main_integration, main_integration_init, NULL);
+  
+  g_assert (connection != NULL);
+
+  _g_dbus_connection_remove_from_main (connection);
+
+  dbus_source = (DBusSource *)
+    g_source_new ((GSourceFuncs*)&dbus_source_funcs,
+		  sizeof (DBusSource));
+  
+  dbus_source->connection = connection;
+  
+  if (!dbus_connection_set_watch_functions (connection,
+                                            add_watch,
+                                            remove_watch,
+                                            watch_toggled,
+                                            dbus_source, NULL))
+    _g_dbus_oom ();
+
+  if (!dbus_connection_set_timeout_functions (connection,
+                                              add_timeout,
+                                              remove_timeout,
+                                              timeout_toggled,
+                                              dbus_source, NULL))
+    _g_dbus_oom ();
+    
+  dbus_connection_set_wakeup_main_function (connection,
+					    wakeup_main,
+					    dbus_source, NULL);
+
+  /* Owned by both connection and mainloop (until destroy) */
+  g_source_attach ((GSource *)dbus_source, NULL);
+
+  if (!dbus_connection_set_data (connection,
+				 main_integration_data_slot,
+				 dbus_source, (DBusFreeFunction)dbus_source_free))
+    _g_dbus_oom ();
+}
+
+void
+_g_dbus_connection_remove_from_main (DBusConnection *connection)
+{
+  g_once (&once_init_main_integration, main_integration_init, NULL);
+
+  if (!dbus_connection_set_data (connection,
+				 main_integration_data_slot,
+				 NULL, NULL))
+    _g_dbus_oom ();
+}
diff --git a/monitor/hal/gvfsdbusutils.h b/monitor/hal/gvfsdbusutils.h
new file mode 100644
index 0000000..9334821
--- /dev/null
+++ b/monitor/hal/gvfsdbusutils.h
@@ -0,0 +1,42 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ */
+
+#ifndef __GVFS_DBUS_UTILS_H__
+#define __GVFS_DBUS_UTILS_H__
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+typedef gboolean (*GFDSourceFunc) (gpointer data,
+				   GIOCondition condition,
+				   int fd);
+
+void         _g_dbus_connection_integrate_with_main (DBusConnection   *connection);
+void         _g_dbus_connection_remove_from_main    (DBusConnection   *connection);
+
+G_END_DECLS
+
+
+#endif /* __GVFS_DBUS_UTILS_H__ */



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