X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libs%2Fgst%2Fnet%2Fgstnettimepacket.c;h=e103e16e821184ab39968332ea8457314bf97aa7;hb=a87b4551a6090663a1714f263d4e20fe75eb46ca;hp=6091c15c2c8687ded495df05bc080e476722c474;hpb=7916e14a2550717a093c9f20df94d7e0ec06e17d;p=platform%2Fupstream%2Fgstreamer.git diff --git a/libs/gst/net/gstnettimepacket.c b/libs/gst/net/gstnettimepacket.c index 6091c15..e103e16 100644 --- a/libs/gst/net/gstnettimepacket.c +++ b/libs/gst/net/gstnettimepacket.c @@ -1,5 +1,7 @@ /* GStreamer * Copyright (C) 2005 Andy Wingo + * Copyright (C) 2010 Tim-Philipp Müller + * Copyright (C) 2012 Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -13,25 +15,26 @@ * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ /** * SECTION:gstnettimepacket + * @title: GstNetTimePacket * @short_description: Helper structure to construct clock packets used * by network clocks. * @see_also: #GstClock, #GstNetClientClock, #GstNetTimeProvider * * Various functions for receiving, sending an serializing #GstNetTimePacket * structures. - * - * Last reviewed on 2005-11-23 (0.9.5) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include + #ifdef __CYGWIN__ # include # include @@ -39,10 +42,12 @@ #include "gstnettimepacket.h" +G_DEFINE_BOXED_TYPE (GstNetTimePacket, gst_net_time_packet, + gst_net_time_packet_copy, gst_net_time_packet_free); /** * gst_net_time_packet_new: - * @buffer: a buffer from which to construct the packet, or NULL + * @buffer: (array): a buffer from which to construct the packet, or NULL * * Creates a new #GstNetTimePacket from a buffer received over the network. The * caller is responsible for ensuring that @buffer is at least @@ -51,7 +56,7 @@ * If @buffer is #NULL, the local and remote times will be set to * #GST_CLOCK_TIME_NONE. * - * MT safe. Caller owns return value (g_free to free). + * MT safe. Caller owns return value (gst_net_time_packet_free to free). * * Returns: The new #GstNetTimePacket. */ @@ -76,6 +81,38 @@ gst_net_time_packet_new (const guint8 * buffer) } /** + * gst_net_time_packet_free: + * @packet: the #GstNetTimePacket + * + * Free @packet. + */ +void +gst_net_time_packet_free (GstNetTimePacket * packet) +{ + g_free (packet); +} + +/** + * gst_net_time_packet_copy: + * @packet: the #GstNetTimePacket + * + * Make a copy of @packet. + * + * Returns: a copy of @packet, free with gst_net_time_packet_free(). + */ +GstNetTimePacket * +gst_net_time_packet_copy (const GstNetTimePacket * packet) +{ + GstNetTimePacket *ret; + + ret = g_new0 (GstNetTimePacket, 1); + ret->local_time = packet->local_time; + ret->remote_time = packet->remote_time; + + return ret; +} + +/** * gst_net_time_packet_serialize: * @packet: the #GstNetTimePacket * @@ -105,95 +142,106 @@ gst_net_time_packet_serialize (const GstNetTimePacket * packet) /** * gst_net_time_packet_receive: - * @fd: a file descriptor created by socket(2) - * @addr: a pointer to a sockaddr to hold the address of the sender - * @len: a pointer to the size of the data pointed to by @addr + * @socket: socket to receive the time packet on + * @src_address: (out): address of variable to return sender address + * @error: return address for a #GError, or NULL * - * Receives a #GstNetTimePacket over a socket. Handles interrupted system calls, - * but otherwise returns NULL on error. See recvfrom(2) for more information on - * how to interpret @sockaddr. - * - * MT safe. Caller owns return value (g_free to free). + * Receives a #GstNetTimePacket over a socket. Handles interrupted system + * calls, but otherwise returns NULL on error. * - * Returns: The new #GstNetTimePacket. + * Returns: (transfer full): a new #GstNetTimePacket, or NULL on error. Free + * with gst_net_time_packet_free() when done. */ GstNetTimePacket * -gst_net_time_packet_receive (gint fd, struct sockaddr * addr, socklen_t * len) +gst_net_time_packet_receive (GSocket * socket, + GSocketAddress ** src_address, GError ** error) { - guint8 buffer[GST_NET_TIME_PACKET_SIZE]; - gint ret; + gchar buffer[GST_NET_TIME_PACKET_SIZE]; + GError *err = NULL; + gssize ret; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); while (TRUE) { - ret = recvfrom (fd, buffer, GST_NET_TIME_PACKET_SIZE, - 0, (struct sockaddr *) addr, len); + ret = g_socket_receive_from (socket, src_address, buffer, + GST_NET_TIME_PACKET_SIZE, NULL, &err); + if (ret < 0) { - if (errno != EAGAIN && errno != EINTR) - goto receive_error; - else + if (err->code == G_IO_ERROR_WOULD_BLOCK) { + g_error_free (err); + err = NULL; continue; + } else { + goto receive_error; + } } else if (ret < GST_NET_TIME_PACKET_SIZE) { goto short_packet; } else { - return gst_net_time_packet_new (buffer); + return gst_net_time_packet_new ((const guint8 *) buffer); } } receive_error: { - GST_DEBUG ("receive error %d: %s (%d)", ret, g_strerror (errno), errno); + GST_DEBUG ("receive error: %s", err->message); + g_propagate_error (error, err); return NULL; } short_packet: { - GST_DEBUG ("someone sent us a short packet (%d < %d)", + GST_DEBUG ("someone sent us a short packet (%" G_GSSIZE_FORMAT " < %d)", ret, GST_NET_TIME_PACKET_SIZE); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "short time packet (%d < %d)", (int) ret, GST_NET_TIME_PACKET_SIZE); return NULL; } } /** * gst_net_time_packet_send: - * @packet: the #GstNetTimePacket - * @fd: a file descriptor created by socket(2) - * @addr: a pointer to a sockaddr to hold the address of the sender - * @len: the size of the data pointed to by @addr + * @packet: the #GstNetTimePacket to send + * @socket: socket to send the time packet on + * @dest_address: address to send the time packet to + * @error: return address for a #GError, or NULL * - * Sends a #GstNetTimePacket over a socket. Essentially a thin wrapper around - * sendto(2) and gst_net_time_packet_serialize(). + * Sends a #GstNetTimePacket over a socket. * * MT safe. * - * Returns: The return value of sendto(2). + * Returns: TRUE if successful, FALSE in case an error occurred. */ -gint -gst_net_time_packet_send (const GstNetTimePacket * packet, gint fd, - struct sockaddr * addr, socklen_t len) +gboolean +gst_net_time_packet_send (const GstNetTimePacket * packet, + GSocket * socket, GSocketAddress * dest_address, GError ** error) { -#ifdef __CYGWIN__ - gint fdflags; -#endif + gboolean was_blocking; guint8 *buffer; - gint ret, send_flags; + gssize res; - g_return_val_if_fail (packet != NULL, -EINVAL); + g_return_val_if_fail (packet != NULL, FALSE); + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + g_return_val_if_fail (G_IS_SOCKET_ADDRESS (dest_address), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); -#ifdef __CYGWIN__ - send_flags = 0; - fdflags = fcntl (fd, F_GETFL); - fcntl (fd, F_SETFL, fdflags | O_NONBLOCK); -#else - send_flags = MSG_DONTWAIT; -#endif + was_blocking = g_socket_get_blocking (socket); + if (was_blocking) + g_socket_set_blocking (socket, FALSE); + + /* FIXME: avoid pointless alloc/free, serialise into stack-allocated buffer */ buffer = gst_net_time_packet_serialize (packet); - ret = sendto (fd, buffer, GST_NET_TIME_PACKET_SIZE, send_flags, addr, len); + res = g_socket_send_to (socket, dest_address, (const gchar *) buffer, + GST_NET_TIME_PACKET_SIZE, NULL, error); -#ifdef __CYGWIN__ - fcntl (fd, F_SETFL, fdflags); -#endif + /* datagram packets should be sent as a whole or not at all */ + g_assert (res < 0 || res == GST_NET_TIME_PACKET_SIZE); g_free (buffer); - return ret; + if (was_blocking) + g_socket_set_blocking (socket, TRUE); + + return (res == GST_NET_TIME_PACKET_SIZE); }