LCOV - code coverage report
Current view: top level - libs/gst/net - gstnettimeprovider.c (source / functions) Hit Total Coverage
Test: GStreamer 0.10.32.1 Lines: 129 183 70.5 %
Date: 2011-03-25 Functions: 12 12 100.0 %
Branches: 43 104 41.3 %

           Branch data     Line data    Source code
       1                 :            : /* GStreamer
       2                 :            :  * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
       3                 :            :  *
       4                 :            :  * This library is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU Library General Public
       6                 :            :  * License as published by the Free Software Foundation; either
       7                 :            :  * version 2 of the License, or (at your option) any later version.
       8                 :            :  *
       9                 :            :  * This library is distributed in the hope that it will be useful,
      10                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12                 :            :  * Library General Public License for more details.
      13                 :            :  *
      14                 :            :  * You should have received a copy of the GNU Library General Public
      15                 :            :  * License along with this library; if not, write to the
      16                 :            :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      17                 :            :  * Boston, MA 02111-1307, USA.
      18                 :            :  */
      19                 :            : /**
      20                 :            :  * SECTION:gstnettimeprovider
      21                 :            :  * @short_description: Special object that exposed the time of a clock
      22                 :            :  *                     on the network.
      23                 :            :  * @see_also: #GstClock, #GstNetClientClock, #GstPipeline
      24                 :            :  *
      25                 :            :  * This object exposes the time of a #GstClock on the network.
      26                 :            :  *
      27                 :            :  * A #GstNetTimeProvider is created with gst_net_time_provider_new() which
      28                 :            :  * takes a #GstClock, an address and a port number as arguments.
      29                 :            :  *
      30                 :            :  * After creating the object, a client clock such as #GstNetClientClock can
      31                 :            :  * query the exposed clock over the network for its values.
      32                 :            :  *
      33                 :            :  * The #GstNetTimeProvider typically wraps the clock used by a #GstPipeline.
      34                 :            :  *
      35                 :            :  * Last reviewed on 2005-11-23 (0.9.5)
      36                 :            :  */
      37                 :            : 
      38                 :            : #ifdef HAVE_CONFIG_H
      39                 :            : #include "config.h"
      40                 :            : #endif
      41                 :            : 
      42                 :            : #include "gstnettimeprovider.h"
      43                 :            : #include "gstnettimepacket.h"
      44                 :            : 
      45                 :            : #include <glib.h>
      46                 :            : 
      47                 :            : #ifdef HAVE_UNISTD_H
      48                 :            : #include <unistd.h>
      49                 :            : #endif
      50                 :            : 
      51                 :            : #if defined (_MSC_VER) && _MSC_VER >= 1400
      52                 :            : #include <io.h>
      53                 :            : #endif
      54                 :            : 
      55                 :            : #ifndef G_OS_WIN32
      56                 :            : #include <sys/ioctl.h>
      57                 :            : #endif
      58                 :            : 
      59                 :            : #ifdef HAVE_FIONREAD_IN_SYS_FILIO
      60                 :            : #include <sys/filio.h>
      61                 :            : #endif
      62                 :            : 
      63                 :            : GST_DEBUG_CATEGORY_STATIC (ntp_debug);
      64                 :            : #define GST_CAT_DEFAULT (ntp_debug)
      65                 :            : 
      66                 :            : #ifdef G_OS_WIN32
      67                 :            : #define close(sock) closesocket(sock)
      68                 :            : #endif
      69                 :            : 
      70                 :            : #define DEFAULT_ADDRESS         "0.0.0.0"
      71                 :            : #define DEFAULT_PORT            5637
      72                 :            : 
      73                 :            : #define IS_ACTIVE(self) (g_atomic_int_get (&((self)->active.active)))
      74                 :            : 
      75                 :            : #ifdef G_OS_WIN32
      76                 :            : #define setsockopt(sock, sol_flags, reuse_flags, ru, sizeofru) setsockopt (sock, sol_flags, reuse_flags, (char *)ru, sizeofru)
      77                 :            : #endif
      78                 :            : enum
      79                 :            : {
      80                 :            :   PROP_0,
      81                 :            :   PROP_PORT,
      82                 :            :   PROP_ADDRESS,
      83                 :            :   PROP_CLOCK,
      84                 :            :   PROP_ACTIVE
      85                 :            :       /* FILL ME */
      86                 :            : };
      87                 :            : 
      88                 :            : #define GST_NET_TIME_PROVIDER_GET_PRIVATE(obj)  \
      89                 :            :    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_NET_TIME_PROVIDER, GstNetTimeProviderPrivate))
      90                 :            : 
      91                 :            : struct _GstNetTimeProviderPrivate
      92                 :            : {
      93                 :            :   GstPollFD sock;
      94                 :            :   GstPoll *fdset;
      95                 :            : };
      96                 :            : 
      97                 :            : static gboolean gst_net_time_provider_start (GstNetTimeProvider * bself);
      98                 :            : static void gst_net_time_provider_stop (GstNetTimeProvider * bself);
      99                 :            : 
     100                 :            : static gpointer gst_net_time_provider_thread (gpointer data);
     101                 :            : 
     102                 :            : static void gst_net_time_provider_finalize (GObject * object);
     103                 :            : static void gst_net_time_provider_set_property (GObject * object, guint prop_id,
     104                 :            :     const GValue * value, GParamSpec * pspec);
     105                 :            : static void gst_net_time_provider_get_property (GObject * object, guint prop_id,
     106                 :            :     GValue * value, GParamSpec * pspec);
     107                 :            : 
     108                 :            : #define _do_init(type) \
     109                 :            :   GST_DEBUG_CATEGORY_INIT (ntp_debug, "nettime", 0, "Network time provider");
     110                 :            : 
     111 [ +  + ][ +  - ]:         23 : GST_BOILERPLATE_FULL (GstNetTimeProvider, gst_net_time_provider, GstObject,
     112                 :         23 :     GST_TYPE_OBJECT, _do_init);
     113                 :            : 
     114                 :            : #ifdef G_OS_WIN32
     115                 :            : static int
     116                 :            : inet_aton (const char *c, struct in_addr *paddr)
     117                 :            : {
     118                 :            :   paddr->s_addr = inet_addr (c);
     119                 :            :   if (paddr->s_addr == INADDR_NONE)
     120                 :            :     return 0;
     121                 :            : 
     122                 :            :   return 1;
     123                 :            : }
     124                 :            : #endif
     125                 :            : 
     126                 :            : static void
     127                 :          3 : gst_net_time_provider_base_init (gpointer g_class)
     128                 :            : {
     129                 :            :   /* Do nothing here */
     130                 :          3 : }
     131                 :            : 
     132                 :            : static void
     133                 :          3 : gst_net_time_provider_class_init (GstNetTimeProviderClass * klass)
     134                 :            : {
     135                 :            :   GObjectClass *gobject_class;
     136                 :            : 
     137                 :          3 :   gobject_class = G_OBJECT_CLASS (klass);
     138                 :            : 
     139                 :            :   g_assert (sizeof (GstClockTime) == 8);
     140                 :            : 
     141                 :          3 :   g_type_class_add_private (klass, sizeof (GstNetTimeProviderPrivate));
     142                 :            : 
     143                 :          3 :   gobject_class->finalize = gst_net_time_provider_finalize;
     144                 :          3 :   gobject_class->set_property = gst_net_time_provider_set_property;
     145                 :          3 :   gobject_class->get_property = gst_net_time_provider_get_property;
     146                 :            : 
     147                 :          3 :   g_object_class_install_property (gobject_class, PROP_PORT,
     148                 :            :       g_param_spec_int ("port", "port",
     149                 :            :           "The port to receive the packets from, 0=allocate", 0, G_MAXUINT16,
     150                 :            :           DEFAULT_PORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     151                 :          3 :   g_object_class_install_property (gobject_class, PROP_ADDRESS,
     152                 :            :       g_param_spec_string ("address", "address",
     153                 :            :           "The address to bind on, as a dotted quad (x.x.x.x)",
     154                 :            :           DEFAULT_ADDRESS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     155                 :          3 :   g_object_class_install_property (gobject_class, PROP_CLOCK,
     156                 :            :       g_param_spec_object ("clock", "Clock",
     157                 :            :           "The clock to export over the network", GST_TYPE_CLOCK,
     158                 :            :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     159                 :          3 :   g_object_class_install_property (gobject_class, PROP_ACTIVE,
     160                 :            :       g_param_spec_boolean ("active", "Active",
     161                 :            :           "TRUE if the clock will respond to queries over the network", TRUE,
     162                 :            :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     163                 :          3 : }
     164                 :            : 
     165                 :            : static void
     166                 :          3 : gst_net_time_provider_init (GstNetTimeProvider * self,
     167                 :            :     GstNetTimeProviderClass * g_class)
     168                 :            : {
     169                 :            : #ifdef G_OS_WIN32
     170                 :            :   WSADATA w;
     171                 :            :   int error = WSAStartup (0x0202, &w);
     172                 :            : 
     173                 :            :   if (error) {
     174                 :            :     GST_DEBUG_OBJECT (self, "Error on WSAStartup");
     175                 :            :   }
     176                 :            :   if (w.wVersion != 0x0202) {
     177                 :            :     WSACleanup ();
     178                 :            :   }
     179                 :            : #endif
     180                 :          3 :   self->priv = GST_NET_TIME_PROVIDER_GET_PRIVATE (self);
     181                 :            : 
     182                 :          3 :   self->port = DEFAULT_PORT;
     183                 :          3 :   self->priv->sock.fd = -1;
     184                 :          3 :   self->address = g_strdup (DEFAULT_ADDRESS);
     185                 :          3 :   self->thread = NULL;
     186                 :          3 :   self->active.active = TRUE;
     187                 :          3 : }
     188                 :            : 
     189                 :            : static void
     190                 :          3 : gst_net_time_provider_finalize (GObject * object)
     191                 :            : {
     192                 :          3 :   GstNetTimeProvider *self = GST_NET_TIME_PROVIDER (object);
     193                 :            : 
     194         [ +  - ]:          3 :   if (self->thread) {
     195                 :          3 :     gst_net_time_provider_stop (self);
     196         [ -  + ]:          3 :     g_assert (self->thread == NULL);
     197                 :            :   }
     198                 :            : 
     199         [ +  - ]:          3 :   if (self->priv->fdset) {
     200                 :          3 :     gst_poll_free (self->priv->fdset);
     201                 :          3 :     self->priv->fdset = NULL;
     202                 :            :   }
     203                 :            : 
     204                 :          3 :   g_free (self->address);
     205                 :          3 :   self->address = NULL;
     206                 :            : 
     207         [ +  - ]:          3 :   if (self->clock)
     208                 :          3 :     gst_object_unref (self->clock);
     209                 :          3 :   self->clock = NULL;
     210                 :            : 
     211                 :            : #ifdef G_OS_WIN32
     212                 :            :   WSACleanup ();
     213                 :            : #endif
     214                 :            : 
     215                 :          3 :   G_OBJECT_CLASS (parent_class)->finalize (object);
     216                 :          3 : }
     217                 :            : 
     218                 :            : static gpointer
     219                 :          3 : gst_net_time_provider_thread (gpointer data)
     220                 :            : {
     221                 :          3 :   GstNetTimeProvider *self = data;
     222                 :            :   struct sockaddr_in tmpaddr;
     223                 :            :   socklen_t len;
     224                 :            :   GstNetTimePacket *packet;
     225                 :            :   gint ret;
     226                 :            : 
     227                 :            :   while (TRUE) {
     228         [ -  + ]:         36 :     GST_LOG_OBJECT (self, "doing select");
     229                 :         36 :     ret = gst_poll_wait (self->priv->fdset, GST_CLOCK_TIME_NONE);
     230         [ -  + ]:         36 :     GST_LOG_OBJECT (self, "select returned %d", ret);
     231                 :            : 
     232         [ +  + ]:         36 :     if (ret <= 0) {
     233         [ +  - ]:          3 :       if (errno == EBUSY) {
     234         [ -  + ]:          3 :         GST_LOG_OBJECT (self, "stop");
     235                 :          3 :         goto stopped;
     236 [ #  # ][ #  # ]:          0 :       } else if (errno != EAGAIN && errno != EINTR)
     237                 :            :         goto select_error;
     238                 :            :       else
     239                 :          0 :         continue;
     240                 :            :     } else {
     241                 :            :       /* got data in */
     242                 :         33 :       len = sizeof (struct sockaddr);
     243                 :            : 
     244                 :         33 :       packet = gst_net_time_packet_receive (self->priv->sock.fd,
     245                 :            :           (struct sockaddr *) &tmpaddr, &len);
     246                 :            : 
     247         [ -  + ]:         33 :       if (!packet)
     248                 :          0 :         goto receive_error;
     249                 :            : 
     250         [ +  - ]:         33 :       if (IS_ACTIVE (self)) {
     251                 :            :         /* do what we were asked to and send the packet back */
     252                 :         33 :         packet->remote_time = gst_clock_get_time (self->clock);
     253                 :            : 
     254                 :            :         /* ignore errors */
     255                 :         33 :         gst_net_time_packet_send (packet, self->priv->sock.fd,
     256                 :            :             (struct sockaddr *) &tmpaddr, len);
     257                 :            :       }
     258                 :            : 
     259                 :         33 :       g_free (packet);
     260                 :            : 
     261                 :         33 :       continue;
     262                 :            :     }
     263                 :            : 
     264                 :            :     g_assert_not_reached ();
     265                 :            : 
     266                 :            :     /* log errors and keep going */
     267                 :            :   select_error:
     268                 :            :     {
     269         [ #  # ]:          0 :       GST_DEBUG_OBJECT (self, "select error %d: %s (%d)", ret,
     270                 :            :           g_strerror (errno), errno);
     271                 :          0 :       continue;
     272                 :            :     }
     273                 :            :   stopped:
     274                 :            :     {
     275         [ -  + ]:          3 :       GST_DEBUG_OBJECT (self, "shutting down");
     276                 :            :       /* close socket */
     277                 :          3 :       return NULL;
     278                 :            :     }
     279                 :            :   receive_error:
     280                 :            :     {
     281         [ #  # ]:          0 :       GST_DEBUG_OBJECT (self, "receive error");
     282                 :          0 :       continue;
     283                 :            :     }
     284                 :            : 
     285                 :            :     g_assert_not_reached ();
     286                 :            : 
     287                 :         33 :   }
     288                 :            : 
     289                 :            :   g_assert_not_reached ();
     290                 :            : 
     291                 :            :   return NULL;
     292                 :            : }
     293                 :            : 
     294                 :            : static void
     295                 :          9 : gst_net_time_provider_set_property (GObject * object, guint prop_id,
     296                 :            :     const GValue * value, GParamSpec * pspec)
     297                 :            : {
     298                 :          9 :   GstNetTimeProvider *self = GST_NET_TIME_PROVIDER (object);
     299                 :          9 :   GstClock **clock_p = &self->clock;
     300                 :            : 
     301   [ +  +  +  -  :          9 :   switch (prop_id) {
                      - ]
     302                 :            :     case PROP_PORT:
     303                 :          3 :       self->port = g_value_get_int (value);
     304                 :          3 :       break;
     305                 :            :     case PROP_ADDRESS:
     306                 :          3 :       g_free (self->address);
     307         [ +  + ]:          3 :       if (g_value_get_string (value) == NULL)
     308                 :          1 :         self->address = g_strdup (DEFAULT_ADDRESS);
     309                 :            :       else
     310                 :          2 :         self->address = g_strdup (g_value_get_string (value));
     311                 :          3 :       break;
     312                 :            :     case PROP_CLOCK:
     313                 :          3 :       gst_object_replace ((GstObject **) clock_p,
     314                 :          3 :           (GstObject *) g_value_get_object (value));
     315                 :          3 :       break;
     316                 :            :     case PROP_ACTIVE:
     317                 :          0 :       g_atomic_int_set (&self->active.active, g_value_get_boolean (value));
     318                 :          0 :       break;
     319                 :            :     default:
     320                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     321                 :          0 :       break;
     322                 :            :   }
     323                 :          9 : }
     324                 :            : 
     325                 :            : static void
     326                 :          2 : gst_net_time_provider_get_property (GObject * object, guint prop_id,
     327                 :            :     GValue * value, GParamSpec * pspec)
     328                 :            : {
     329                 :          2 :   GstNetTimeProvider *self = GST_NET_TIME_PROVIDER (object);
     330                 :            : 
     331   [ +  -  -  -  :          2 :   switch (prop_id) {
                      - ]
     332                 :            :     case PROP_PORT:
     333                 :          2 :       g_value_set_int (value, self->port);
     334                 :          2 :       break;
     335                 :            :     case PROP_ADDRESS:
     336                 :          0 :       g_value_set_string (value, self->address);
     337                 :          0 :       break;
     338                 :            :     case PROP_CLOCK:
     339                 :          0 :       g_value_set_object (value, self->clock);
     340                 :          0 :       break;
     341                 :            :     case PROP_ACTIVE:
     342                 :          0 :       g_value_set_boolean (value, IS_ACTIVE (self));
     343                 :          0 :       break;
     344                 :            :     default:
     345                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     346                 :          0 :       break;
     347                 :            :   }
     348                 :          2 : }
     349                 :            : 
     350                 :            : static gboolean
     351                 :          3 : gst_net_time_provider_start (GstNetTimeProvider * self)
     352                 :            : {
     353                 :            :   gint ru;
     354                 :            :   struct sockaddr_in my_addr;
     355                 :            :   socklen_t len;
     356                 :            :   int port;
     357                 :            :   gint ret;
     358                 :            :   GError *error;
     359                 :            : 
     360         [ -  + ]:          3 :   if ((ret = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
     361                 :          0 :     goto no_socket;
     362                 :            : 
     363                 :          3 :   self->priv->sock.fd = ret;
     364                 :            : 
     365                 :          3 :   ru = 1;
     366                 :          3 :   ret =
     367                 :          3 :       setsockopt (self->priv->sock.fd, SOL_SOCKET, SO_REUSEADDR, &ru,
     368                 :            :       sizeof (ru));
     369         [ -  + ]:          3 :   if (ret < 0)
     370                 :          0 :     goto setsockopt_error;
     371                 :            : 
     372                 :          3 :   memset (&my_addr, 0, sizeof (my_addr));
     373                 :          3 :   my_addr.sin_family = AF_INET; /* host byte order */
     374                 :          3 :   my_addr.sin_port = htons ((gint16) self->port);       /* short, network byte order */
     375                 :          3 :   my_addr.sin_addr.s_addr = INADDR_ANY;
     376         [ +  - ]:          3 :   if (self->address) {
     377                 :          3 :     ret = inet_aton (self->address, &my_addr.sin_addr);
     378         [ -  + ]:          3 :     if (ret == 0)
     379                 :          0 :       goto invalid_address_error;
     380                 :            :   }
     381                 :            : 
     382         [ -  + ]:          3 :   GST_DEBUG_OBJECT (self, "binding on port %d", self->port);
     383                 :          3 :   ret =
     384                 :          3 :       bind (self->priv->sock.fd, (struct sockaddr *) &my_addr,
     385                 :            :       sizeof (my_addr));
     386         [ -  + ]:          3 :   if (ret < 0)
     387                 :          0 :     goto bind_error;
     388                 :            : 
     389                 :          3 :   len = sizeof (my_addr);
     390                 :          3 :   ret = getsockname (self->priv->sock.fd, (struct sockaddr *) &my_addr, &len);
     391         [ -  + ]:          3 :   if (ret < 0)
     392                 :          0 :     goto getsockname_error;
     393                 :            : 
     394                 :          3 :   port = ntohs (my_addr.sin_port);
     395         [ -  + ]:          3 :   GST_DEBUG_OBJECT (self, "bound, on port %d", port);
     396                 :            : 
     397         [ +  - ]:          3 :   if (port != self->port) {
     398                 :          3 :     self->port = port;
     399         [ -  + ]:          3 :     GST_DEBUG_OBJECT (self, "notifying %d", port);
     400                 :          3 :     g_object_notify (G_OBJECT (self), "port");
     401                 :            :   }
     402                 :            : 
     403                 :          3 :   gst_poll_add_fd (self->priv->fdset, &self->priv->sock);
     404                 :          3 :   gst_poll_fd_ctl_read (self->priv->fdset, &self->priv->sock, TRUE);
     405                 :            : 
     406                 :          3 :   self->thread = g_thread_create (gst_net_time_provider_thread, self, TRUE,
     407                 :            :       &error);
     408         [ -  + ]:          3 :   if (!self->thread)
     409                 :          0 :     goto no_thread;
     410                 :            : 
     411                 :          3 :   return TRUE;
     412                 :            : 
     413                 :            :   /* ERRORS */
     414                 :            : no_socket:
     415                 :            :   {
     416         [ #  # ]:          0 :     GST_ERROR_OBJECT (self, "socket failed %d: %s (%d)", ret,
     417                 :            :         g_strerror (errno), errno);
     418                 :          0 :     return FALSE;
     419                 :            :   }
     420                 :            : setsockopt_error:
     421                 :            :   {
     422                 :          0 :     close (self->priv->sock.fd);
     423                 :          0 :     self->priv->sock.fd = -1;
     424         [ #  # ]:          0 :     GST_ERROR_OBJECT (self, "setsockopt failed %d: %s (%d)", ret,
     425                 :            :         g_strerror (errno), errno);
     426                 :          0 :     return FALSE;
     427                 :            :   }
     428                 :            : invalid_address_error:
     429                 :            :   {
     430                 :          0 :     close (self->priv->sock.fd);
     431                 :          0 :     self->priv->sock.fd = -1;
     432         [ #  # ]:          0 :     GST_ERROR_OBJECT (self, "invalid network address %s: %s (%d)",
     433                 :            :         self->address, g_strerror (errno), errno);
     434                 :          0 :     return FALSE;
     435                 :            :   }
     436                 :            : bind_error:
     437                 :            :   {
     438                 :          0 :     close (self->priv->sock.fd);
     439                 :          0 :     self->priv->sock.fd = -1;
     440         [ #  # ]:          0 :     GST_ERROR_OBJECT (self, "bind failed %d: %s (%d)", ret,
     441                 :            :         g_strerror (errno), errno);
     442                 :          0 :     return FALSE;
     443                 :            :   }
     444                 :            : getsockname_error:
     445                 :            :   {
     446                 :          0 :     close (self->priv->sock.fd);
     447                 :          0 :     self->priv->sock.fd = -1;
     448         [ #  # ]:          0 :     GST_ERROR_OBJECT (self, "getsockname failed %d: %s (%d)", ret,
     449                 :            :         g_strerror (errno), errno);
     450                 :          0 :     return FALSE;
     451                 :            :   }
     452                 :            : no_thread:
     453                 :            :   {
     454                 :          0 :     gst_poll_remove_fd (self->priv->fdset, &self->priv->sock);
     455                 :          0 :     close (self->priv->sock.fd);
     456                 :          0 :     self->priv->sock.fd = -1;
     457         [ #  # ]:          0 :     GST_ERROR_OBJECT (self, "could not create thread: %s", error->message);
     458                 :          0 :     g_error_free (error);
     459                 :          3 :     return FALSE;
     460                 :            :   }
     461                 :            : }
     462                 :            : 
     463                 :            : static void
     464                 :          3 : gst_net_time_provider_stop (GstNetTimeProvider * self)
     465                 :            : {
     466                 :          3 :   gst_poll_set_flushing (self->priv->fdset, TRUE);
     467                 :          3 :   g_thread_join (self->thread);
     468                 :          3 :   self->thread = NULL;
     469                 :            : 
     470         [ +  - ]:          3 :   if (self->priv->sock.fd != -1) {
     471                 :          3 :     gst_poll_remove_fd (self->priv->fdset, &self->priv->sock);
     472                 :          3 :     close (self->priv->sock.fd);
     473                 :          3 :     self->priv->sock.fd = -1;
     474                 :            :   }
     475                 :          3 : }
     476                 :            : 
     477                 :            : /**
     478                 :            :  * gst_net_time_provider_new:
     479                 :            :  * @clock: a #GstClock to export over the network
     480                 :            :  * @address: an address to bind on as a dotted quad (xxx.xxx.xxx.xxx), or NULL
     481                 :            :  *           to bind to all addresses
     482                 :            :  * @port: a port to bind on, or 0 to let the kernel choose
     483                 :            :  *
     484                 :            :  * Allows network clients to get the current time of @clock.
     485                 :            :  *
     486                 :            :  * Returns: the new #GstNetTimeProvider, or NULL on error
     487                 :            :  */
     488                 :            : GstNetTimeProvider *
     489                 :          3 : gst_net_time_provider_new (GstClock * clock, const gchar * address, gint port)
     490                 :            : {
     491                 :            :   GstNetTimeProvider *ret;
     492                 :            : 
     493 [ +  - ][ -  + ]:          3 :   g_return_val_if_fail (clock && GST_IS_CLOCK (clock), NULL);
         [ +  - ][ -  + ]
                 [ +  - ]
     494 [ +  - ][ +  - ]:          3 :   g_return_val_if_fail (port >= 0 && port <= G_MAXUINT16, NULL);
     495                 :            : 
     496                 :          3 :   ret = g_object_new (GST_TYPE_NET_TIME_PROVIDER, "clock", clock, "address",
     497                 :            :       address, "port", port, NULL);
     498                 :            : 
     499         [ -  + ]:          3 :   if ((ret->priv->fdset = gst_poll_new (TRUE)) == NULL)
     500                 :          0 :     goto no_fdset;
     501                 :            : 
     502         [ -  + ]:          3 :   if (!gst_net_time_provider_start (ret))
     503                 :          0 :     goto failed_start;
     504                 :            : 
     505                 :            :   /* all systems go, cap'n */
     506                 :          3 :   return ret;
     507                 :            : 
     508                 :            : no_fdset:
     509                 :            :   {
     510         [ #  # ]:          0 :     GST_ERROR_OBJECT (ret, "could not create an fdset: %s (%d)",
     511                 :            :         g_strerror (errno), errno);
     512                 :          0 :     gst_object_unref (ret);
     513                 :          0 :     return NULL;
     514                 :            :   }
     515                 :            : failed_start:
     516                 :            :   {
     517                 :            :     /* already printed a nice error */
     518                 :          0 :     gst_object_unref (ret);
     519                 :          3 :     return NULL;
     520                 :            :   }
     521                 :            : }

Generated by: LCOV version 1.9