gst-libs/gst/rtsp/gstrtspconnection.*: Small cleanups.

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.
This commit is contained in:
Wim Taymans 2007-08-17 13:42:49 +00:00
parent c17a721e0a
commit 01d9553d43
4 changed files with 158 additions and 49 deletions

View file

@ -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> 2007-08-16 Wim Taymans <wim.taymans@gmail.com>
Patch by: Olivier Crete <tester at tester ca> Patch by: Olivier Crete <tester at tester ca>

View file

@ -70,6 +70,7 @@
/* we include this here to get the G_OS_* defines */ /* we include this here to get the G_OS_* defines */
#include <glib.h> #include <glib.h>
#include <gst/gst.h>
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
#include <winsock2.h> #include <winsock2.h>
@ -109,9 +110,11 @@ G_STMT_START { \
} G_STMT_END } G_STMT_END
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
#define FIONREAD_TYPE gulong
#define IOCTL_SOCKET ioctlsocket #define IOCTL_SOCKET ioctlsocket
#define CLOSE_SOCKET(sock) closesocket(sock); #define CLOSE_SOCKET(sock) closesocket(sock);
#else #else
#define FIONREAD_TYPE gint
#define IOCTL_SOCKET ioctl #define IOCTL_SOCKET ioctl
#define CLOSE_SOCKET(sock) close(sock); #define CLOSE_SOCKET(sock) close(sock);
#endif #endif
@ -290,7 +293,7 @@ gst_rtsp_connection_connect (GstRTSPConnection * conn, GTimeVal * timeout)
FD_ZERO (&readfds); FD_ZERO (&readfds);
FD_SET (READ_SOCKET (conn), &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_sec = timeout->tv_sec;
tv.tv_usec = timeout->tv_usec; tv.tv_usec = timeout->tv_usec;
tvp = &tv; tvp = &tv;
@ -405,7 +408,6 @@ gst_rtsp_connection_write (GstRTSPConnection * conn, const guint8 * data,
FD_ZERO (&writefds); FD_ZERO (&writefds);
FD_SET (conn->fd, &writefds); FD_SET (conn->fd, &writefds);
FD_ZERO (&readfds); FD_ZERO (&readfds);
FD_SET (READ_SOCKET (conn), &readfds);
max_fd = MAX (conn->fd, READ_SOCKET (conn)); max_fd = MAX (conn->fd, READ_SOCKET (conn));
@ -422,6 +424,9 @@ gst_rtsp_connection_write (GstRTSPConnection * conn, const guint8 * data,
while (towrite > 0) { while (towrite > 0) {
gint written; 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 { do {
retval = select (max_fd + 1, &readfds, &writefds, NULL, tvp); retval = select (max_fd + 1, &readfds, &writefds, NULL, tvp);
} while ((retval == -1 && errno == EINTR)); } while ((retval == -1 && errno == EINTR));
@ -432,20 +437,8 @@ gst_rtsp_connection_write (GstRTSPConnection * conn, const guint8 * data,
if (retval == -1) if (retval == -1)
goto select_error; goto select_error;
if (FD_ISSET (READ_SOCKET (conn), &readfds)) { 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;
}
}
goto stopped; goto stopped;
}
/* now we can write */ /* now we can write */
written = write (conn->fd, data, towrite); written = write (conn->fd, data, towrite);
@ -815,13 +808,8 @@ gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data, guint size,
fd_set readfds; fd_set readfds;
guint toread; guint toread;
gint retval; gint retval;
struct timeval tv_timeout, *ptv_timeout = NULL; struct timeval tv_timeout, *ptv_timeout;
FIONREAD_TYPE avail;
#ifndef G_OS_WIN32
gint avail;
#else
gulong avail;
#endif
g_return_val_if_fail (conn != NULL, GST_RTSP_EINVAL); g_return_val_if_fail (conn != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (data != 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; 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 /* 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.*/ * there is enough data to read, skip the select call al together.*/
if (IOCTL_SOCKET (conn->fd, FIONREAD, &avail) < 0) 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) else if (avail >= toread)
goto do_read; 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_ZERO (&readfds);
FD_SET (conn->fd, &readfds); FD_SET (conn->fd, &readfds);
FD_SET (READ_SOCKET (conn), &readfds);
while (toread > 0) { while (toread > 0) {
gint bytes; 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 { do {
retval = select (FD_SETSIZE, &readfds, NULL, NULL, ptv_timeout); retval = select (FD_SETSIZE, &readfds, NULL, NULL, ptv_timeout);
} while ((retval == -1 && errno == EINTR)); } while ((retval == -1 && errno == EINTR));
@ -863,20 +855,8 @@ gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data, guint size,
if (retval == 0) if (retval == 0)
goto select_timeout; goto select_timeout;
if (FD_ISSET (READ_SOCKET (conn), &readfds)) { 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;
}
}
goto stopped; goto stopped;
}
do_read: do_read:
/* if we get here there is activity on the real fd since the select /* if we get here there is activity on the real fd since the select
@ -1168,6 +1148,103 @@ gst_rtsp_connection_free (GstRTSPConnection * conn)
return res; return res;
} }
/**
* 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: * gst_rtsp_connection_next_timeout:
* @conn: a #GstRTSPConnection * @conn: a #GstRTSPConnection

View file

@ -99,6 +99,10 @@ GstRTSPResult gst_rtsp_connection_send (GstRTSPConnection *conn, G
GstRTSPResult gst_rtsp_connection_receive (GstRTSPConnection *conn, GstRTSPMessage *message, GstRTSPResult gst_rtsp_connection_receive (GstRTSPConnection *conn, GstRTSPMessage *message,
GTimeVal *timeout); GTimeVal *timeout);
/* status management */
GstRTSPResult gst_rtsp_connection_poll (GstRTSPConnection *conn, GstRTSPEvent events,
GstRTSPEvent *revents, GTimeVal *timeout);
/* reset the timeout */ /* reset the timeout */
GstRTSPResult gst_rtsp_connection_next_timeout (GstRTSPConnection *conn, GTimeVal *timeout); GstRTSPResult gst_rtsp_connection_next_timeout (GstRTSPConnection *conn, GTimeVal *timeout);
GstRTSPResult gst_rtsp_connection_reset_timeout (GstRTSPConnection *conn); GstRTSPResult gst_rtsp_connection_reset_timeout (GstRTSPConnection *conn);

View file

@ -100,9 +100,21 @@ typedef enum {
GST_RTSP_ENOTIP = -13, GST_RTSP_ENOTIP = -13,
GST_RTSP_ETIMEOUT = -14, GST_RTSP_ETIMEOUT = -14,
GST_RTSP_ELAST = -15, GST_RTSP_ELAST = -15
} GstRTSPResult; } 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: * GstRTSPFamily:
* @GST_RTSP_FAM_NONE: unknown network family * @GST_RTSP_FAM_NONE: unknown network family
@ -114,7 +126,7 @@ typedef enum {
typedef enum { typedef enum {
GST_RTSP_FAM_NONE, GST_RTSP_FAM_NONE,
GST_RTSP_FAM_INET, GST_RTSP_FAM_INET,
GST_RTSP_FAM_INET6, GST_RTSP_FAM_INET6
} GstRTSPFamily; } GstRTSPFamily;
/** /**
@ -134,7 +146,7 @@ typedef enum {
GST_RTSP_STATE_READY, GST_RTSP_STATE_READY,
GST_RTSP_STATE_SEEKING, GST_RTSP_STATE_SEEKING,
GST_RTSP_STATE_PLAYING, GST_RTSP_STATE_PLAYING,
GST_RTSP_STATE_RECORDING, GST_RTSP_STATE_RECORDING
} GstRTSPState; } GstRTSPState;
/** /**
@ -146,7 +158,7 @@ typedef enum {
*/ */
typedef enum { typedef enum {
GST_RTSP_VERSION_INVALID = 0x00, GST_RTSP_VERSION_INVALID = 0x00,
GST_RTSP_VERSION_1_0 = 0x10, GST_RTSP_VERSION_1_0 = 0x10
} GstRTSPVersion; } GstRTSPVersion;
/** /**
@ -178,7 +190,7 @@ typedef enum {
GST_RTSP_REDIRECT = (1 << 7), GST_RTSP_REDIRECT = (1 << 7),
GST_RTSP_SETUP = (1 << 8), GST_RTSP_SETUP = (1 << 8),
GST_RTSP_SET_PARAMETER = (1 << 9), GST_RTSP_SET_PARAMETER = (1 << 9),
GST_RTSP_TEARDOWN = (1 << 10), GST_RTSP_TEARDOWN = (1 << 10)
} GstRTSPMethod; } GstRTSPMethod;
/** /**
@ -312,7 +324,7 @@ typedef enum {
GST_RTSP_STS_SERVICE_UNAVAILABLE = 503, GST_RTSP_STS_SERVICE_UNAVAILABLE = 503,
GST_RTSP_STS_GATEWAY_TIMEOUT = 504, GST_RTSP_STS_GATEWAY_TIMEOUT = 504,
GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED = 505, GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED = 505,
GST_RTSP_STS_OPTION_NOT_SUPPORTED = 551, GST_RTSP_STS_OPTION_NOT_SUPPORTED = 551
} GstRTSPStatusCode; } GstRTSPStatusCode;
gchar* gst_rtsp_strresult (GstRTSPResult result); gchar* gst_rtsp_strresult (GstRTSPResult result);