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;
};
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;
}
}