Commit 9c42c06d authored by George Kiagiadakis's avatar George Kiagiadakis

udpsrc: avoid doing select() if there are messages available

Again, the rule of thumb: return execution to recvmmsg() as fast as possible.
There is no need to select() when there are already packets available!
parent 7e6c77e0
......@@ -1058,45 +1058,53 @@ retry:
if (!gst_udpsrc_reset_input_messages (udpsrc))
goto memory_alloc_error;
do {
gint64 timeout;
GST_LOG_OBJECT (udpsrc, "reading up to %d messages", udpsrc->input_msgs->len);
try_again = FALSE;
n_recv_msgs = g_socket_receive_messages (udpsrc->used_socket,
&g_array_index (udpsrc->input_msgs, GInputMessage, 0),
udpsrc->input_msgs->len, flags, udpsrc->cancellable, &err);
if (udpsrc->timeout)
timeout = udpsrc->timeout / 1000;
else
timeout = -1;
if (n_recv_msgs < 0) {
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
do {
gint64 timeout;
GST_LOG_OBJECT (udpsrc, "doing select, timeout %" G_GINT64_FORMAT, timeout);
try_again = FALSE;
if (udpsrc->timeout)
timeout = udpsrc->timeout / 1000;
else
timeout = -1;
GST_LOG_OBJECT (udpsrc, "doing select, timeout %" G_GINT64_FORMAT,
timeout);
if (!g_socket_condition_timed_wait (udpsrc->used_socket, G_IO_IN | G_IO_PRI,
timeout, udpsrc->cancellable, &err)) {
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_BUSY)
|| g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
goto stopped;
} else if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_TIMED_OUT)) {
g_clear_error (&err);
/* timeout, post element message */
gst_element_post_message (GST_ELEMENT_CAST (udpsrc),
gst_message_new_element (GST_OBJECT_CAST (udpsrc),
gst_structure_new ("GstUDPSrcTimeout",
"timeout", G_TYPE_UINT64, udpsrc->timeout, NULL)));
} else {
goto select_error;
}
if (!g_socket_condition_timed_wait (udpsrc->used_socket,
G_IO_IN | G_IO_PRI, timeout, udpsrc->cancellable, &err)) {
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_BUSY)
|| g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
goto stopped;
} else if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_TIMED_OUT)) {
g_clear_error (&err);
/* timeout, post element message */
gst_element_post_message (GST_ELEMENT_CAST (udpsrc),
gst_message_new_element (GST_OBJECT_CAST (udpsrc),
gst_structure_new ("GstUDPSrcTimeout",
"timeout", G_TYPE_UINT64, udpsrc->timeout, NULL)));
} else {
goto select_error;
}
try_again = TRUE;
try_again = TRUE;
}
} while (G_UNLIKELY (try_again));
goto retry;
}
} while (G_UNLIKELY (try_again));
GST_LOG_OBJECT (udpsrc, "reading up to %d messages", udpsrc->input_msgs->len);
n_recv_msgs = g_socket_receive_messages (udpsrc->used_socket,
&g_array_index (udpsrc->input_msgs, GInputMessage, 0),
udpsrc->input_msgs->len, flags, udpsrc->cancellable, &err);
if (g_cancellable_is_cancelled (udpsrc->cancellable))
goto stopped;
if (G_UNLIKELY (n_recv_msgs < 0)) {
/* G_IO_ERROR_HOST_UNREACHABLE for a UDP socket means that a packet sent
* with udpsink generated a "port unreachable" ICMP response. We ignore
* that and try again.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment