gst-libs/gst/rtsp/gstrtspconnection.*: Small cleanups.
authorWim Taymans <wim.taymans@gmail.com>
Fri, 17 Aug 2007 13:42:49 +0000 (13:42 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Fri, 17 Aug 2007 13:42:49 +0000 (13:42 +0000)
Original commit message from CVS:
* gst-libs/gst/rtsp/gstrtspconnection.c:
(gst_rtsp_connection_connect), (gst_rtsp_connection_write),
(gst_rtsp_connection_read), (gst_rtsp_connection_poll):
* gst-libs/gst/rtsp/gstrtspconnection.h:
Small cleanups.
On shutdown, don't read the control socket yet.
Set timeout value correctly in all cases.
Add function to check if the server accepts reads or writes.
API: gst_rtsp_connection_poll()
* gst-libs/gst/rtsp/gstrtspdefs.h:
Fix compilation with -pedantic.
Add enum for _poll.

ChangeLog
gst-libs/gst/rtsp/gstrtspconnection.c
gst-libs/gst/rtsp/gstrtspconnection.h
gst-libs/gst/rtsp/gstrtspdefs.h

index b3ee37e..fba1e7b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2007-08-17  Wim Taymans  <wim.taymans@gmail.com>
+
+       * gst-libs/gst/rtsp/gstrtspconnection.c:
+       (gst_rtsp_connection_connect), (gst_rtsp_connection_write),
+       (gst_rtsp_connection_read), (gst_rtsp_connection_poll):
+       * gst-libs/gst/rtsp/gstrtspconnection.h:
+       Small cleanups.
+       On shutdown, don't read the control socket yet.
+       Set timeout value correctly in all cases.
+       Add function to check if the server accepts reads or writes.
+       API: gst_rtsp_connection_poll()
+
+       * gst-libs/gst/rtsp/gstrtspdefs.h:
+       Fix compilation with -pedantic.
+       Add enum for _poll.
+
 2007-08-16  Wim Taymans  <wim.taymans@gmail.com>
 
        Patch by: Olivier Crete  <tester at tester ca>
index 522e1a0..b764767 100644 (file)
@@ -70,6 +70,7 @@
 
 /* we include this here to get the G_OS_* defines */
 #include <glib.h>
+#include <gst/gst.h>
 
 #ifdef G_OS_WIN32
 #include <winsock2.h>
@@ -109,9 +110,11 @@ G_STMT_START {                                  \
 } G_STMT_END
 
 #ifdef G_OS_WIN32
+#define FIONREAD_TYPE gulong
 #define IOCTL_SOCKET ioctlsocket
 #define CLOSE_SOCKET(sock) closesocket(sock);
 #else
+#define FIONREAD_TYPE gint
 #define IOCTL_SOCKET ioctl
 #define CLOSE_SOCKET(sock) close(sock);
 #endif
@@ -290,7 +293,7 @@ gst_rtsp_connection_connect (GstRTSPConnection * conn, GTimeVal * timeout)
   FD_ZERO (&readfds);
   FD_SET (READ_SOCKET (conn), &readfds);
 
-  if (timeout->tv_sec != 0 || timeout->tv_usec != 0) {
+  if (timeout) {
     tv.tv_sec = timeout->tv_sec;
     tv.tv_usec = timeout->tv_usec;
     tvp = &tv;
@@ -405,7 +408,6 @@ gst_rtsp_connection_write (GstRTSPConnection * conn, const guint8 * data,
   FD_ZERO (&writefds);
   FD_SET (conn->fd, &writefds);
   FD_ZERO (&readfds);
-  FD_SET (READ_SOCKET (conn), &readfds);
 
   max_fd = MAX (conn->fd, READ_SOCKET (conn));
 
@@ -422,6 +424,9 @@ gst_rtsp_connection_write (GstRTSPConnection * conn, const guint8 * data,
   while (towrite > 0) {
     gint written;
 
+    /* set bit inside the loop for when we loop to read the rest of the data */
+    FD_SET (READ_SOCKET (conn), &readfds);
+
     do {
       retval = select (max_fd + 1, &readfds, &writefds, NULL, tvp);
     } while ((retval == -1 && errno == EINTR));
@@ -432,20 +437,8 @@ gst_rtsp_connection_write (GstRTSPConnection * conn, const guint8 * data,
     if (retval == -1)
       goto select_error;
 
-    if (FD_ISSET (READ_SOCKET (conn), &readfds)) {
-      /* read all stop commands */
-      while (TRUE) {
-        gchar command;
-        int res;
-
-        READ_COMMAND (conn, command, res);
-        if (res <= 0) {
-          /* no more commands */
-          break;
-        }
-      }
+    if (FD_ISSET (READ_SOCKET (conn), &readfds))
       goto stopped;
-    }
 
     /* now we can write */
     written = write (conn->fd, data, towrite);
@@ -815,13 +808,8 @@ gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data, guint size,
   fd_set readfds;
   guint toread;
   gint retval;
-  struct timeval tv_timeout, *ptv_timeout = NULL;
-
-#ifndef G_OS_WIN32
-  gint avail;
-#else
-  gulong avail;
-#endif
+  struct timeval tv_timeout, *ptv_timeout;
+  FIONREAD_TYPE avail;
 
   g_return_val_if_fail (conn != NULL, GST_RTSP_EINVAL);
   g_return_val_if_fail (data != NULL, GST_RTSP_EINVAL);
@@ -831,6 +819,14 @@ gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data, guint size,
 
   toread = size;
 
+  /* configure timeout if any */
+  if (timeout != NULL) {
+    tv_timeout.tv_sec = timeout->tv_sec;
+    tv_timeout.tv_usec = timeout->tv_usec;
+    ptv_timeout = &tv_timeout;
+  } else
+    ptv_timeout = NULL;
+
   /* if the call fails, just go in the select.. it should not fail. Else if
    * there is enough data to read, skip the select call al together.*/
   if (IOCTL_SOCKET (conn->fd, FIONREAD, &avail) < 0)
@@ -838,20 +834,16 @@ gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data, guint size,
   else if (avail >= toread)
     goto do_read;
 
-  /* configure timeout if any */
-  if (timeout != NULL) {
-    tv_timeout.tv_sec = timeout->tv_sec;
-    tv_timeout.tv_usec = timeout->tv_usec;
-    ptv_timeout = &tv_timeout;
-  }
-
   FD_ZERO (&readfds);
   FD_SET (conn->fd, &readfds);
-  FD_SET (READ_SOCKET (conn), &readfds);
 
   while (toread > 0) {
     gint bytes;
 
+    /* set inside the loop so that when we did not read enough and we have to
+     * continue, we still have the cancel socket bit set */
+    FD_SET (READ_SOCKET (conn), &readfds);
+
     do {
       retval = select (FD_SETSIZE, &readfds, NULL, NULL, ptv_timeout);
     } while ((retval == -1 && errno == EINTR));
@@ -863,20 +855,8 @@ gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data, guint size,
     if (retval == 0)
       goto select_timeout;
 
-    if (FD_ISSET (READ_SOCKET (conn), &readfds)) {
-      /* read all stop commands */
-      while (TRUE) {
-        gchar command;
-        int res;
-
-        READ_COMMAND (conn, command, res);
-        if (res <= 0) {
-          /* no more commands */
-          break;
-        }
-      }
+    if (FD_ISSET (READ_SOCKET (conn), &readfds))
       goto stopped;
-    }
 
   do_read:
     /* if we get here there is activity on the real fd since the select
@@ -1169,6 +1149,103 @@ gst_rtsp_connection_free (GstRTSPConnection * conn)
 }
 
 /**
+ * gst_rtsp_connection_poll:
+ * @conn: a #GstRTSPConnection
+ * @events: a bitmask of #GstRTSPEvent flags to check
+ * @revents: location for result flags 
+ * @timeout: a timeout
+ *
+ * Wait up to the specified @timeout for the connection to become available for
+ * at least one of the operations specified in @events. When the function returns
+ * with #GST_RTSP_OK, @revents will contain a bitmask of available operations on
+ * @conn.
+ *
+ * @timeout can be #NULL, in which case this function might block forever.
+ *
+ * This function can be canceled with gst_rtsp_connection_flush().
+ * 
+ * Returns: #GST_RTSP_OK on success.
+ *
+ * Since: 0.10.15
+ */
+GstRTSPResult
+gst_rtsp_connection_poll (GstRTSPConnection * conn, GstRTSPEvent events,
+    GstRTSPEvent * revents, GTimeVal * timeout)
+{
+  fd_set writefds, *pwritefds;
+  fd_set readfds;
+  int max_fd;
+  gint retval;
+  struct timeval tv, *tvp;
+
+  g_return_val_if_fail (conn != NULL, GST_RTSP_EINVAL);
+  g_return_val_if_fail (events != 0, GST_RTSP_EINVAL);
+  g_return_val_if_fail (revents != NULL, GST_RTSP_EINVAL);
+
+  if (events & GST_RTSP_EV_WRITE) {
+    /* add fd to writer set when asked to */
+    FD_ZERO (&writefds);
+    FD_SET (conn->fd, &writefds);
+    pwritefds = &writefds;
+  } else
+    pwritefds = NULL;
+
+  /* always add cancel socket to readfds */
+  FD_ZERO (&readfds);
+  FD_SET (READ_SOCKET (conn), &readfds);
+  if (events & GST_RTSP_EV_READ) {
+    /* add fd to reader set when asked to */
+    FD_SET (conn->fd, &readfds);
+  }
+  max_fd = MAX (conn->fd, READ_SOCKET (conn));
+
+  if (timeout) {
+    tv.tv_sec = timeout->tv_sec;
+    tv.tv_usec = timeout->tv_usec;
+    tvp = &tv;
+  } else
+    tvp = NULL;
+
+  do {
+    retval = select (max_fd + 1, &readfds, pwritefds, NULL, tvp);
+  } while ((retval == -1 && errno == EINTR));
+
+  if (retval == 0)
+    goto select_timeout;
+
+  if (retval == -1)
+    goto select_error;
+
+  if (FD_ISSET (READ_SOCKET (conn), &readfds))
+    goto stopped;
+
+  *revents = 0;
+  if (events & GST_RTSP_EV_READ) {
+    if (FD_ISSET (conn->fd, &readfds))
+      *revents |= GST_RTSP_EV_READ;
+  }
+  if (events & GST_RTSP_EV_WRITE) {
+    if (FD_ISSET (conn->fd, &writefds))
+      *revents |= GST_RTSP_EV_WRITE;
+  }
+  return GST_RTSP_OK;
+
+  /* ERRORS */
+select_timeout:
+  {
+    return GST_RTSP_ETIMEOUT;
+  }
+select_error:
+  {
+    return GST_RTSP_ESYS;
+  }
+stopped:
+  {
+    return GST_RTSP_EINTR;
+  }
+}
+
+/**
  * gst_rtsp_connection_next_timeout:
  * @conn: a #GstRTSPConnection
  * @timeout: a timeout
index e6112ab..3479308 100644 (file)
@@ -99,6 +99,10 @@ GstRTSPResult      gst_rtsp_connection_send          (GstRTSPConnection *conn, G
 GstRTSPResult      gst_rtsp_connection_receive       (GstRTSPConnection *conn, GstRTSPMessage *message,
                                                       GTimeVal *timeout);
 
+/* status management */
+GstRTSPResult      gst_rtsp_connection_poll          (GstRTSPConnection *conn, GstRTSPEvent events,
+                                                      GstRTSPEvent *revents, GTimeVal *timeout);
+
 /* reset the timeout */
 GstRTSPResult      gst_rtsp_connection_next_timeout  (GstRTSPConnection *conn, GTimeVal *timeout);
 GstRTSPResult      gst_rtsp_connection_reset_timeout (GstRTSPConnection *conn);
index b6d9dfa..cf2058b 100644 (file)
@@ -100,10 +100,22 @@ typedef enum {
   GST_RTSP_ENOTIP      = -13,
   GST_RTSP_ETIMEOUT    = -14,
 
-  GST_RTSP_ELAST       = -15,
+  GST_RTSP_ELAST       = -15
 } GstRTSPResult;
 
 /**
+ * GstRTSPEvent:
+ * @GST_RTSP_EV_READ: connection is readable
+ * @GST_RTSP_EV_WRITE: connection is writable
+ *
+ * The possible events for the connection.
+ */
+typedef enum {
+  GST_RTSP_EV_READ  = (1 << 0),
+  GST_RTSP_EV_WRITE = (1 << 1)
+} GstRTSPEvent;
+
+/**
  * GstRTSPFamily:
  * @GST_RTSP_FAM_NONE: unknown network family
  * @GST_RTSP_FAM_INET: internet
@@ -114,7 +126,7 @@ typedef enum {
 typedef enum {
   GST_RTSP_FAM_NONE,
   GST_RTSP_FAM_INET,
-  GST_RTSP_FAM_INET6,
+  GST_RTSP_FAM_INET6
 } GstRTSPFamily;
 
 /**
@@ -134,7 +146,7 @@ typedef enum {
   GST_RTSP_STATE_READY,
   GST_RTSP_STATE_SEEKING,
   GST_RTSP_STATE_PLAYING,
-  GST_RTSP_STATE_RECORDING,
+  GST_RTSP_STATE_RECORDING
 } GstRTSPState;
 
 /**
@@ -146,7 +158,7 @@ typedef enum {
  */
 typedef enum {
   GST_RTSP_VERSION_INVALID = 0x00,
-  GST_RTSP_VERSION_1_0     = 0x10,
+  GST_RTSP_VERSION_1_0     = 0x10
 } GstRTSPVersion;
 
 /**
@@ -178,7 +190,7 @@ typedef enum {
   GST_RTSP_REDIRECT         = (1 <<  7),
   GST_RTSP_SETUP            = (1 <<  8),
   GST_RTSP_SET_PARAMETER    = (1 <<  9),
-  GST_RTSP_TEARDOWN         = (1 << 10),
+  GST_RTSP_TEARDOWN         = (1 << 10)
 } GstRTSPMethod;
 
 /**
@@ -312,7 +324,7 @@ typedef enum {
   GST_RTSP_STS_SERVICE_UNAVAILABLE                  = 503, 
   GST_RTSP_STS_GATEWAY_TIMEOUT                      = 504, 
   GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED           = 505, 
-  GST_RTSP_STS_OPTION_NOT_SUPPORTED                 = 551
+  GST_RTSP_STS_OPTION_NOT_SUPPORTED                 = 551
 } GstRTSPStatusCode;
 
 gchar*             gst_rtsp_strresult          (GstRTSPResult result);