[cheese] monitor: Implement GAsyncInitable interface



commit efa35e4b25c203ac92b59950e112120ae76a4d4b
Author: Ondrej Holy <oholy redhat com>
Date:   Thu Nov 2 09:45:33 2017 +0100

    monitor: Implement GAsyncInitable interface
    
    Monitor initialization may block if external camera is connected,
    probably due to some kernel bug. It causes freezes for applications,
    which is not acceptable. Let's implement GAsyncInitable interface,
    so it can be initialized asynchronously.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=782627

 libcheese/cheese-camera-device-monitor.c |   89 ++++++++++++++++++++++++++++--
 libcheese/cheese-camera-device-monitor.h |    6 ++
 2 files changed, 89 insertions(+), 6 deletions(-)
---
diff --git a/libcheese/cheese-camera-device-monitor.c b/libcheese/cheese-camera-device-monitor.c
index 48520ed..5b4b43b 100644
--- a/libcheese/cheese-camera-device-monitor.c
+++ b/libcheese/cheese-camera-device-monitor.c
@@ -47,7 +47,14 @@ struct _CheeseCameraDeviceMonitorPrivate
   GstDeviceMonitor *monitor;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (CheeseCameraDeviceMonitor, cheese_camera_device_monitor, G_TYPE_OBJECT)
+static void initable_iface_init       (GInitableIface      *initable_iface);
+static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
+
+G_DEFINE_TYPE_WITH_CODE (CheeseCameraDeviceMonitor, cheese_camera_device_monitor,
+                         G_TYPE_OBJECT,
+                         G_ADD_PRIVATE (CheeseCameraDeviceMonitor)
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
+                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init));
 
 #define CHEESE_CAMERA_DEVICE_MONITOR_ERROR cheese_camera_device_monitor_error_quark ()
 
@@ -271,10 +278,13 @@ cheese_camera_device_monitor_class_init (CheeseCameraDeviceMonitorClass *klass)
                                            G_TYPE_NONE, 1, CHEESE_TYPE_CAMERA_DEVICE);
 }
 
-static void
-cheese_camera_device_monitor_init (CheeseCameraDeviceMonitor *monitor)
+static gboolean
+initable_init (GInitable     *initable,
+               GCancellable  *cancellable,
+               GError       **error)
 {
-    CheeseCameraDeviceMonitorPrivate *priv = cheese_camera_device_monitor_get_instance_private (monitor);
+  CheeseCameraDeviceMonitor *monitor = CHEESE_CAMERA_DEVICE_MONITOR (initable);
+  CheeseCameraDeviceMonitorPrivate *priv = cheese_camera_device_monitor_get_instance_private (monitor);
   GstBus *bus;
   GstCaps *caps;
 
@@ -289,17 +299,84 @@ cheese_camera_device_monitor_init (CheeseCameraDeviceMonitor *monitor)
   gst_caps_unref (caps);
 
   gst_device_monitor_start (priv->monitor);
+
+  return TRUE;
+}
+
+static void
+initable_iface_init (GInitableIface *initable_iface)
+{
+  initable_iface->init = initable_init;
+}
+
+static void
+async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
+{
+  /* Run GInitable code in thread. */
+}
+
+static void
+cheese_camera_device_monitor_init (CheeseCameraDeviceMonitor *monitor)
+{
+  /* Let GInitable initialize it. */
 }
 
 /**
  * cheese_camera_device_monitor_new:
  *
- * Returns a new #CheeseCameraDeviceMonitor object.
+ * Returns a new #CheeseCameraDeviceMonitor object. The initialization may block.
+ * See cheese_camera_device_monitor_new_async() for the asynchronous version.
  *
  * Return value: a new #CheeseCameraDeviceMonitor object.
  **/
 CheeseCameraDeviceMonitor *
 cheese_camera_device_monitor_new (void)
 {
-  return g_object_new (CHEESE_TYPE_CAMERA_DEVICE_MONITOR, NULL);
+  return g_initable_new (CHEESE_TYPE_CAMERA_DEVICE_MONITOR, NULL, NULL, NULL);
+}
+
+/**
+ * cheese_camera_device_monitor_new_async:
+ * @cancellable: a #GCancellable or NULL
+ * @callback: a GAsyncReadyCallback to call when the initialization is finished
+ * @user_data: user data to pass to callback
+ *
+ * Creates a new #CheeseCameraDeviceMonitor object asynchronously. Callback
+ * will be called when it is done. Use cheese_camera_device_monitor_new_finish()
+ * to get the result.
+ *
+ * See cheese_camera_device_monitor_new() for the synchronous version.
+ **/
+void
+cheese_camera_device_monitor_new_async (GCancellable *cancellable,
+                                        GAsyncReadyCallback callback,
+                                        gpointer user_data)
+{
+  g_async_initable_new_async (CHEESE_TYPE_CAMERA_DEVICE_MONITOR, 0, cancellable, callback, user_data, NULL);
+}
+
+/**
+ * cheese_camera_device_monitor_new_finish:
+ * @result: the GAsyncResult from the callback
+ * @error: return location for errors, or NULL to ignore
+ *
+ * Finishes creating a new #CheeseCameraDeviceMonitor object.
+ *
+ * Return value: a new #CheeseCameraDeviceMonitor object or NULL if error is set.
+ **/
+CheeseCameraDeviceMonitor *
+cheese_camera_device_monitor_new_finish (GAsyncResult *result,
+                                         GError      **error)
+{
+  GObject *ret;
+  GObject *source;
+
+  source = g_async_result_get_source_object (result);
+  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, error);
+  g_object_unref (source);
+
+  if (ret != NULL)
+    return CHEESE_CAMERA_DEVICE_MONITOR (ret);
+  else
+    return NULL;
 }
diff --git a/libcheese/cheese-camera-device-monitor.h b/libcheese/cheese-camera-device-monitor.h
index f11d0a4..2432bd6 100644
--- a/libcheese/cheese-camera-device-monitor.h
+++ b/libcheese/cheese-camera-device-monitor.h
@@ -23,6 +23,7 @@
 #ifndef __CHEESE_CAMERA_DEVICE_MONITOR_H__
 #define __CHEESE_CAMERA_DEVICE_MONITOR_H__
 
+#include <gio/gio.h>
 #include <glib-object.h>
 #include <cheese-camera-device.h>
 
@@ -75,6 +76,11 @@ struct _CheeseCameraDeviceMonitorClass
 
 GType                      cheese_camera_device_monitor_get_type (void);
 CheeseCameraDeviceMonitor *cheese_camera_device_monitor_new (void);
+void                       cheese_camera_device_monitor_new_async (GCancellable       *cancellable,
+                                                                   GAsyncReadyCallback callback,
+                                                                   gpointer            user_data);
+CheeseCameraDeviceMonitor *cheese_camera_device_monitor_new_finish (GAsyncResult *result,
+                                                                    GError      **error);
 void                       cheese_camera_device_monitor_coldplug (CheeseCameraDeviceMonitor *monitor);
 
 G_END_DECLS


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