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>
Patch by: Olivier Crete <tester at tester ca>

View 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
@ -1168,6 +1148,103 @@ gst_rtsp_connection_free (GstRTSPConnection * conn)
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:
* @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,
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);

View file

@ -100,9 +100,21 @@ 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
@ -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);