[glib] gsocket: Fix error behaviour of g_socket_send_messages()
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gsocket: Fix error behaviour of g_socket_send_messages()
- Date: Thu, 1 Oct 2015 13:17:22 +0000 (UTC)
commit 1086507e75580083aef46ad3072e9ff7869c2bc4
Author: Philip Withnall <philip withnall collabora co uk>
Date: Mon Aug 17 18:10:43 2015 +0100
gsocket: Fix error behaviour of g_socket_send_messages()
If an error in the underlying sendmmsg() syscall occurs after
successfully sending one or more messages, g_socket_send_messages()
should return the number of messages successfully sent, rather than an
error. This mirrors the documented sendmmsg() behaviour.
This is a slight behaviour change for g_socket_send_messages(), but as
it relaxes the error reporting (reporting errors in fewer situations
than before), it should not cause problems.
https://bugzilla.gnome.org/show_bug.cgi?id=751924
gio/gsocket.c | 32 +++++++++++---------------------
gio/tests/socket.c | 21 +++++++++++++++++++--
2 files changed, 30 insertions(+), 23 deletions(-)
---
diff --git a/gio/gsocket.c b/gio/gsocket.c
index a0759d4..310238e 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -4295,7 +4295,9 @@ g_socket_send_message (GSocket *socket,
* notified of a %G_IO_OUT condition. (On Windows in particular, this is
* very common due to the way the underlying APIs work.)
*
- * On error -1 is returned and @error is set accordingly.
+ * On error -1 is returned and @error is set accordingly. An error will only
+ * be returned if zero messages could be sent; otherwise the number of messages
+ * successfully sent before the error will be returned.
*
* Returns: number of messages sent, or -1 on error. Note that the number of
* messages sent may be smaller than @num_messages if the socket is
@@ -4351,7 +4353,7 @@ g_socket_send_messages_with_timeout (GSocket *socket,
#if !defined (G_OS_WIN32) && defined (HAVE_SENDMMSG)
{
struct mmsghdr *msgvec;
- gint i, num_sent, result, max_sent;
+ gint i, num_sent;
#ifdef UIO_MAXIOV
#define MAX_NUM_MESSAGES UIO_MAXIOV
@@ -4383,9 +4385,7 @@ g_socket_send_messages_with_timeout (GSocket *socket,
}
}
- num_sent = result = 0;
- max_sent = num_messages;
- while (num_sent < num_messages)
+ for (num_sent = 0; num_sent < num_messages;)
{
gint ret;
@@ -4418,32 +4418,22 @@ g_socket_send_messages_with_timeout (GSocket *socket,
continue;
}
- if (num_sent > 0 &&
- (errsv == EWOULDBLOCK ||
- errsv == EAGAIN))
- {
- max_sent = num_sent;
- break;
- }
+ /* If any messages were successfully sent, do not error. */
+ if (num_sent > 0)
+ break;
socket_set_error_lazy (error, errsv, _("Error sending message: %s"));
- /* we have to iterate over all messages below now, because we don't
- * know where between num_sent and num_messages the error occured */
- max_sent = num_messages;
-
- result = -1;
- break;
+ return -1;
}
num_sent += ret;
- result = num_sent;
}
- for (i = 0; i < max_sent; ++i)
+ for (i = 0; i < num_sent; ++i)
messages[i].bytes_sent = msgvec[i].msg_len;
- return result;
+ return num_sent;
}
#else
{
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index 15fb61a..a5b2573 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -703,14 +703,31 @@ test_ip_sync_dgram (GSocketFamily family)
m[1].bytes_sent = 0;
m[2].bytes_sent = 0;
- /* now try to generate an error by omitting the destination address on [1] */
+ /* now try to generate an early return by omitting the destination address on [1] */
m[1].address = NULL;
len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (len, ==, 1);
+
+ g_assert_cmpint (m[0].bytes_sent, ==, 3);
+ g_assert_cmpint (m[1].bytes_sent, ==, 0);
+ g_assert_cmpint (m[2].bytes_sent, ==, 0);
+
+ /* reset since we're re-using the message structs */
+ m[0].bytes_sent = 0;
+ m[1].bytes_sent = 0;
+ m[2].bytes_sent = 0;
+
+ /* now try to generate an error by omitting all destination addresses */
+ m[0].address = NULL;
+ m[1].address = NULL;
+ m[2].address = NULL;
+ len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
g_clear_error (&error);
g_assert_cmpint (len, ==, -1);
- g_assert_cmpint (m[0].bytes_sent, ==, 3);
+ g_assert_cmpint (m[0].bytes_sent, ==, 0);
g_assert_cmpint (m[1].bytes_sent, ==, 0);
g_assert_cmpint (m[2].bytes_sent, ==, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]