gst-libs/gst/rtsp/gstrtspconnection.c: Make sure we can not cancel in the middle of receiving a message.

Original commit message from CVS:
Patch by: Tommi Myöhänen <ext-tommi dot myohanen at nokia dot com>
* gst-libs/gst/rtsp/gstrtspconnection.c:
(gst_rtsp_connection_read_internal), (gst_rtsp_connection_read),
(read_body), (gst_rtsp_connection_receive):
Make sure we can not cancel in the middle of receiving a message.
Fixes #475731.
This commit is contained in:
Tommi Myöhänen 2007-09-11 19:07:57 +00:00 committed by Wim Taymans
parent 1004fb0603
commit 840c5cd805
2 changed files with 51 additions and 14 deletions

View file

@ -1,3 +1,13 @@
2007-09-11 Wim Taymans <wim.taymans@gmail.com>
Patch by: Tommi Myöhänen <ext-tommi dot myohanen at nokia dot com>
* gst-libs/gst/rtsp/gstrtspconnection.c:
(gst_rtsp_connection_read_internal), (gst_rtsp_connection_read),
(read_body), (gst_rtsp_connection_receive):
Make sure we can not cancel in the middle of receiving a message.
Fixes #475731.
2007-09-11 Tim-Philipp Müller <tim at centricular dot net> 2007-09-11 Tim-Philipp Müller <tim at centricular dot net>
Patch by: Josep Torra Valles <josep@fluendo.com> Patch by: Josep Torra Valles <josep@fluendo.com>

View file

@ -787,23 +787,25 @@ no_column:
} }
/** /**
* gst_rtsp_connection_read: * gst_rtsp_connection_read_internal:
* @conn: a #GstRTSPConnection * @conn: a #GstRTSPConnection
* @data: the data to read * @data: the data to read
* @size: the size of @data * @size: the size of @data
* @timeout: a timeout value or #NULL * @timeout: a timeout value or #NULL
* @allow_interrupt: can the pending read be interrupted
* *
* Attempt to read @size bytes into @data from the connected @conn, blocking up to * Attempt to read @size bytes into @data from the connected @conn, blocking up to
* the specified @timeout. @timeout can be #NULL, in which case this function * the specified @timeout. @timeout can be #NULL, in which case this function
* might block forever. * might block forever.
* *
* This function can be canceled with gst_rtsp_connection_flush(). * This function can be canceled with gst_rtsp_connection_flush() only if the
* @allow_interrupt is set.
* *
* Returns: #GST_RTSP_OK on success. * Returns: #GST_RTSP_OK on success.
*/ */
GstRTSPResult static GstRTSPResult
gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data, guint size, gst_rtsp_connection_read_internal (GstRTSPConnection * conn, guint8 * data,
GTimeVal * timeout) guint size, GTimeVal * timeout, gboolean allow_interrupt)
{ {
fd_set readfds; fd_set readfds;
guint toread; guint toread;
@ -842,6 +844,7 @@ gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data, guint size,
/* set inside the loop so that when we did not read enough and we have to /* 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 */ * continue, we still have the cancel socket bit set */
if (allow_interrupt)
FD_SET (READ_SOCKET (conn), &readfds); FD_SET (READ_SOCKET (conn), &readfds);
do { do {
@ -898,6 +901,29 @@ read_error:
} }
} }
/**
* gst_rtsp_connection_read:
* @conn: a #GstRTSPConnection
* @data: the data to read
* @size: the size of @data
* @timeout: a timeout value or #NULL
*
* Attempt to read @size bytes into @data from the connected @conn, blocking up to
* the specified @timeout. @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.
*/
GstRTSPResult
gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data, guint size,
GTimeVal * timeout)
{
return gst_rtsp_connection_read_internal (conn, data, size, timeout, TRUE);
}
static GstRTSPResult static GstRTSPResult
read_body (GstRTSPConnection * conn, glong content_length, GstRTSPMessage * msg, read_body (GstRTSPConnection * conn, glong content_length, GstRTSPMessage * msg,
GTimeVal * timeout) GTimeVal * timeout)
@ -914,8 +940,8 @@ read_body (GstRTSPConnection * conn, glong content_length, GstRTSPMessage * msg,
body = g_malloc (content_length + 1); body = g_malloc (content_length + 1);
body[content_length] = '\0'; body[content_length] = '\0';
GST_RTSP_CHECK (gst_rtsp_connection_read (conn, body, content_length, GST_RTSP_CHECK (gst_rtsp_connection_read_internal (conn, body, content_length,
timeout), read_error); timeout, FALSE), read_error);
content_length += 1; content_length += 1;
@ -969,8 +995,9 @@ gst_rtsp_connection_receive (GstRTSPConnection * conn, GstRTSPMessage * message,
guint8 c; guint8 c;
/* read first character, this identifies data messages */ /* read first character, this identifies data messages */
GST_RTSP_CHECK (gst_rtsp_connection_read (conn, &c, 1, timeout), /* This is the only read() that we allow to be interrupted */
read_error); GST_RTSP_CHECK (gst_rtsp_connection_read_internal (conn, &c, 1, timeout,
TRUE), read_error);
/* check for data packet, first character is $ */ /* check for data packet, first character is $ */
if (c == '$') { if (c == '$') {
@ -979,15 +1006,15 @@ gst_rtsp_connection_receive (GstRTSPConnection * conn, GstRTSPMessage * message,
/* data packets are $<1 byte channel><2 bytes length,BE><data bytes> */ /* data packets are $<1 byte channel><2 bytes length,BE><data bytes> */
/* read channel, which is the next char */ /* read channel, which is the next char */
GST_RTSP_CHECK (gst_rtsp_connection_read (conn, &c, 1, timeout), GST_RTSP_CHECK (gst_rtsp_connection_read_internal (conn, &c, 1, timeout,
read_error); FALSE), read_error);
/* now we create a data message */ /* now we create a data message */
gst_rtsp_message_init_data (message, c); gst_rtsp_message_init_data (message, c);
/* next two bytes are the length of the data */ /* next two bytes are the length of the data */
GST_RTSP_CHECK (gst_rtsp_connection_read (conn, (guint8 *) & size, 2, GST_RTSP_CHECK (gst_rtsp_connection_read_internal (conn,
timeout), read_error); (guint8 *) & size, 2, timeout, FALSE), read_error);
size = GUINT16_FROM_BE (size); size = GUINT16_FROM_BE (size);