nettimeprovider: Use GInitable instead of having a new() function that can return NULL

Bindings don't like that much and as we're using GIO here anyway we can as
well use GInitable for possibly failing initialization.
This commit is contained in:
Sebastian Dröge 2016-01-04 10:39:27 +02:00
parent 5dc8cea6f4
commit 23abc425d4

View file

@ -76,7 +76,10 @@ struct _GstNetTimeProviderPrivate
gboolean made_cancel_fd; 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 void gst_net_time_provider_stop (GstNetTimeProvider * bself);
static gpointer gst_net_time_provider_thread (gpointer data); 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); GValue * value, GParamSpec * pspec);
#define _do_init \ #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 #define gst_net_time_provider_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstNetTimeProvider, gst_net_time_provider, 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 static gboolean
gst_net_time_provider_start (GstNetTimeProvider * self) gst_net_time_provider_start (GstNetTimeProvider * self, GError ** error)
{ {
GSocketAddress *socket_addr, *bound_addr; GSocketAddress *socket_addr, *bound_addr;
GInetAddress *inet_addr; GInetAddress *inet_addr;
GPollFD dummy_pollfd; GPollFD dummy_pollfd;
GSocket *socket; GSocket *socket;
GError *err = NULL;
int port; int port;
gchar *address; gchar *address;
GError *err = NULL;
if (self->priv->address) { if (self->priv->address) {
inet_addr = g_inet_address_new_from_string (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; goto invalid_address;
}
} else { } else {
inet_addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); 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), socket = g_socket_new (g_inet_address_get_family (inet_addr),
G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err); G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err);
if (err != NULL) if (!socket)
goto no_socket; goto no_socket;
GST_DEBUG_OBJECT (self, "binding on port %d", self->priv->port); GST_DEBUG_OBJECT (self, "binding on port %d", self->priv->port);
socket_addr = g_inet_socket_address_new (inet_addr, 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 (socket_addr);
g_object_unref (inet_addr); g_object_unref (inet_addr);
if (err != NULL)
goto bind_error;
bound_addr = g_socket_get_local_address (socket, NULL); bound_addr = g_socket_get_local_address (socket, NULL);
port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (bound_addr)); port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (bound_addr));
inet_addr = inet_addr =
@ -337,7 +346,7 @@ gst_net_time_provider_start (GstNetTimeProvider * self)
self->priv->thread = g_thread_try_new ("GstNetTimeProvider", self->priv->thread = g_thread_try_new ("GstNetTimeProvider",
gst_net_time_provider_thread, self, &err); gst_net_time_provider_thread, self, &err);
if (err != NULL) if (!self->priv->thread)
goto no_thread; goto no_thread;
return TRUE; return TRUE;
@ -346,26 +355,27 @@ gst_net_time_provider_start (GstNetTimeProvider * self)
invalid_address: invalid_address:
{ {
GST_ERROR_OBJECT (self, "invalid address: %s", self->priv->address); GST_ERROR_OBJECT (self, "invalid address: %s", self->priv->address);
g_propagate_error (error, err);
return FALSE; return FALSE;
} }
no_socket: no_socket:
{ {
GST_ERROR_OBJECT (self, "could not create socket: %s", err->message); 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); g_object_unref (inet_addr);
return FALSE; return FALSE;
} }
bind_error: bind_error:
{ {
GST_ERROR_OBJECT (self, "bind failed: %s", err->message); GST_ERROR_OBJECT (self, "bind failed: %s", err->message);
g_error_free (err); g_propagate_error (error, err);
g_object_unref (socket); g_object_unref (socket);
return FALSE; return FALSE;
} }
no_thread: no_thread:
{ {
GST_ERROR_OBJECT (self, "could not create thread: %s", err->message); 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); g_object_unref (self->priv->socket);
self->priv->socket = NULL; self->priv->socket = NULL;
g_object_unref (self->priv->cancel); g_object_unref (self->priv->cancel);
@ -397,6 +407,23 @@ gst_net_time_provider_stop (GstNetTimeProvider * self)
GST_INFO_OBJECT (self, "stopped"); 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: * gst_net_time_provider_new:
* @clock: a #GstClock to export over the network * @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 (clock && GST_IS_CLOCK (clock), NULL);
g_return_val_if_fail (port >= 0 && port <= G_MAXUINT16, NULL); g_return_val_if_fail (port >= 0 && port <= G_MAXUINT16, NULL);
ret = g_object_new (GST_TYPE_NET_TIME_PROVIDER, "clock", clock, "address", ret =
address, "port", port, NULL); 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; return ret;
failed_start:
{
/* already printed a nice error */
gst_object_unref (ret);
return NULL;
}
} }