diff --git a/libs/gst/net/gstnettimeprovider.c b/libs/gst/net/gstnettimeprovider.c index f1371e2ef7..0025936e0b 100644 --- a/libs/gst/net/gstnettimeprovider.c +++ b/libs/gst/net/gstnettimeprovider.c @@ -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); + ret = + g_initable_new (GST_TYPE_NET_TIME_PROVIDER, NULL, NULL, "clock", clock, + "address", address, "port", port, NULL); - if (!gst_net_time_provider_start (ret)) - goto failed_start; - - /* all systems go, cap'n */ return ret; - -failed_start: - { - /* already printed a nice error */ - gst_object_unref (ret); - return NULL; - } }