nettimeprovider: Use GInitable instead of having a new() function that can return...
authorSebastian Dröge <sebastian@centricular.com>
Mon, 4 Jan 2016 08:39:27 +0000 (10:39 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 4 Jan 2016 08:40:35 +0000 (10:40 +0200)
Bindings don't like that much and as we're using GIO here anyway we can as
well use GInitable for possibly failing initialization.

libs/gst/net/gstnettimeprovider.c

index f1371e2..0025936 100644 (file)
@@ -76,7 +76,10 @@ struct _GstNetTimeProviderPrivate
   gboolean made_cancel_fd;
 };
 
-static gboolean gst_net_time_provider_start (GstNetTimeProvider * bself);
+static void gst_net_time_provider_initable_iface_init (gpointer g_iface);
+
+static gboolean gst_net_time_provider_start (GstNetTimeProvider * bself,
+    GError ** error);
 static void gst_net_time_provider_stop (GstNetTimeProvider * bself);
 
 static gpointer gst_net_time_provider_thread (gpointer data);
@@ -88,7 +91,8 @@ static void gst_net_time_provider_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
 #define _do_init \
-  GST_DEBUG_CATEGORY_INIT (ntp_debug, "nettime", 0, "Network time provider");
+  GST_DEBUG_CATEGORY_INIT (ntp_debug, "nettime", 0, "Network time provider"); \
+  G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gst_net_time_provider_initable_iface_init)
 
 #define gst_net_time_provider_parent_class parent_class
 G_DEFINE_TYPE_WITH_CODE (GstNetTimeProvider, gst_net_time_provider,
@@ -272,20 +276,24 @@ gst_net_time_provider_get_property (GObject * object, guint prop_id,
 }
 
 static gboolean
-gst_net_time_provider_start (GstNetTimeProvider * self)
+gst_net_time_provider_start (GstNetTimeProvider * self, GError ** error)
 {
   GSocketAddress *socket_addr, *bound_addr;
   GInetAddress *inet_addr;
   GPollFD dummy_pollfd;
   GSocket *socket;
-  GError *err = NULL;
   int port;
   gchar *address;
+  GError *err = NULL;
 
   if (self->priv->address) {
     inet_addr = g_inet_address_new_from_string (self->priv->address);
-    if (inet_addr == NULL)
+    if (inet_addr == NULL) {
+      err =
+          g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
+          "Failed to parse address '%s'", self->priv->address);
       goto invalid_address;
+    }
   } else {
     inet_addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
   }
@@ -294,18 +302,19 @@ gst_net_time_provider_start (GstNetTimeProvider * self)
   socket = g_socket_new (g_inet_address_get_family (inet_addr),
       G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err);
 
-  if (err != NULL)
+  if (!socket)
     goto no_socket;
 
   GST_DEBUG_OBJECT (self, "binding on port %d", self->priv->port);
   socket_addr = g_inet_socket_address_new (inet_addr, self->priv->port);
-  g_socket_bind (socket, socket_addr, TRUE, &err);
+  if (!g_socket_bind (socket, socket_addr, TRUE, &err)) {
+    g_object_unref (socket_addr);
+    g_object_unref (inet_addr);
+    goto bind_error;
+  }
   g_object_unref (socket_addr);
   g_object_unref (inet_addr);
 
-  if (err != NULL)
-    goto bind_error;
-
   bound_addr = g_socket_get_local_address (socket, NULL);
   port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (bound_addr));
   inet_addr =
@@ -337,7 +346,7 @@ gst_net_time_provider_start (GstNetTimeProvider * self)
   self->priv->thread = g_thread_try_new ("GstNetTimeProvider",
       gst_net_time_provider_thread, self, &err);
 
-  if (err != NULL)
+  if (!self->priv->thread)
     goto no_thread;
 
   return TRUE;
@@ -346,26 +355,27 @@ gst_net_time_provider_start (GstNetTimeProvider * self)
 invalid_address:
   {
     GST_ERROR_OBJECT (self, "invalid address: %s", self->priv->address);
+    g_propagate_error (error, err);
     return FALSE;
   }
 no_socket:
   {
     GST_ERROR_OBJECT (self, "could not create socket: %s", err->message);
-    g_error_free (err);
+    g_propagate_error (error, err);
     g_object_unref (inet_addr);
     return FALSE;
   }
 bind_error:
   {
     GST_ERROR_OBJECT (self, "bind failed: %s", err->message);
-    g_error_free (err);
+    g_propagate_error (error, err);
     g_object_unref (socket);
     return FALSE;
   }
 no_thread:
   {
     GST_ERROR_OBJECT (self, "could not create thread: %s", err->message);
-    g_error_free (err);
+    g_propagate_error (error, err);
     g_object_unref (self->priv->socket);
     self->priv->socket = NULL;
     g_object_unref (self->priv->cancel);
@@ -397,6 +407,23 @@ gst_net_time_provider_stop (GstNetTimeProvider * self)
   GST_INFO_OBJECT (self, "stopped");
 }
 
+static gboolean
+gst_net_time_provider_initable_init (GInitable * initable,
+    GCancellable * cancellable, GError ** error)
+{
+  GstNetTimeProvider *self = GST_NET_TIME_PROVIDER (initable);
+
+  return gst_net_time_provider_start (self, error);
+}
+
+static void
+gst_net_time_provider_initable_iface_init (gpointer g_iface)
+{
+  GInitableIface *iface = g_iface;
+
+  iface->init = gst_net_time_provider_initable_init;
+}
+
 /**
  * gst_net_time_provider_new:
  * @clock: a #GstClock to export over the network
@@ -416,19 +443,9 @@ gst_net_time_provider_new (GstClock * clock, const gchar * address, gint port)
   g_return_val_if_fail (clock && GST_IS_CLOCK (clock), NULL);
   g_return_val_if_fail (port >= 0 && port <= G_MAXUINT16, NULL);
 
-  ret = g_object_new (GST_TYPE_NET_TIME_PROVIDER, "clock", clock, "address",
-      address, "port", port, NULL);
-
-  if (!gst_net_time_provider_start (ret))
-    goto failed_start;
+  ret =
+      g_initable_new (GST_TYPE_NET_TIME_PROVIDER, NULL, NULL, "clock", clock,
+      "address", address, "port", port, NULL);
 
-  /* all systems go, cap'n */
   return ret;
-
-failed_start:
-  {
-    /* already printed a nice error */
-    gst_object_unref (ret);
-    return NULL;
-  }
 }