[glib: 7/15] Add g_socket_send_message_with_timeout()
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 7/15] Add g_socket_send_message_with_timeout()
- Date: Thu, 24 Jan 2019 14:43:39 +0000 (UTC)
commit f0a11b27274747499e4f31deca23fca51e830caf
Author: Sebastian Dröge <sebastian centricular com>
Date: Fri Sep 14 10:28:12 2018 +0300
Add g_socket_send_message_with_timeout()
gio/gsocket.c | 153 ++++++++++++++++++++++++++++++++++++++--------------------
gio/gsocket.h | 13 ++++-
2 files changed, 113 insertions(+), 53 deletions(-)
---
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 8ceaa16d3..ecb233230 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -194,17 +194,6 @@ g_socket_receive_messages_with_timeout (GSocket *socket,
gint64 timeout,
GCancellable *cancellable,
GError **error);
-static gssize
-g_socket_send_message_with_timeout (GSocket *socket,
- GSocketAddress *address,
- GOutputVector *vectors,
- gint num_vectors,
- GSocketControlMessage **messages,
- gint num_messages,
- gint flags,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error);
static gint
g_socket_send_messages_with_timeout (GSocket *socket,
GOutputMessage *messages,
@@ -4606,22 +4595,61 @@ g_socket_send_message (GSocket *socket,
GCancellable *cancellable,
GError **error)
{
- return g_socket_send_message_with_timeout (socket, address,
- vectors, num_vectors,
- messages, num_messages, flags,
- socket->priv->blocking ? -1 : 0,
- cancellable, error);
+ GPollableReturn res;
+ gsize bytes_written = 0;
+
+ res = g_socket_send_message_with_timeout (socket, address,
+ vectors, num_vectors,
+ messages, num_messages, flags,
+ socket->priv->blocking ? -1 : 0,
+ &bytes_written,
+ cancellable, error);
+
+ if (res == G_POLLABLE_RETURN_WOULD_BLOCK)
+ socket_set_error_lazy (error, EWOULDBLOCK, _("Error sending message: %s"));
+
+ return res == G_POLLABLE_RETURN_OK ? bytes_written : -1;
}
-static gssize
+/**
+ * g_socket_send_message_with_timeout:
+ * @socket: a #GSocket
+ * @address: (nullable): a #GSocketAddress, or %NULL
+ * @vectors: (array length=num_vectors): an array of #GOutputVector structs
+ * @num_vectors: the number of elements in @vectors, or -1
+ * @messages: (array length=num_messages) (nullable): a pointer to an
+ * array of #GSocketControlMessages, or %NULL.
+ * @num_messages: number of elements in @messages, or -1.
+ * @flags: an int containing #GSocketMsgFlags flags
+ * @timeout: the maximum time (in microseconds) to wait, or -1
+ * @bytes_written: (out) (optional): location to store the number of bytes that were written to the socket
+ * @cancellable: (nullable): a %GCancellable or %NULL
+ * @error: #GError for error reporting, or %NULL to ignore.
+ *
+ * This behaves exactly the same as g_socket_send_message(), except that
+ * the choice of timeout behavior is determined by the @timeout argument
+ * rather than by @socket's properties.
+ *
+ * On error %G_POLLABLE_RETURN_FAILED is returned and @error is set accordingly, or
+ * if the socket is currently not writable %G_POLLABLE_RETURN_WOULD_BLOCK is
+ * returned. @bytes_written will contain 0 in both cases.
+ *
+ * Returns: %G_POLLABLE_RETURN_OK if all data was successfully written,
+ * %G_POLLABLE_RETURN_WOULD_BLOCK if the socket is currently not writable, or
+ * %G_POLLABLE_RETURN_FAILED if an error happened and @error is set.
+ *
+ * Since: 2.60
+ */
+GPollableReturn
g_socket_send_message_with_timeout (GSocket *socket,
GSocketAddress *address,
- GOutputVector *vectors,
+ const GOutputVector *vectors,
gint num_vectors,
GSocketControlMessage **messages,
gint num_messages,
gint flags,
gint64 timeout,
+ gsize *bytes_written,
GCancellable *cancellable,
GError **error)
{
@@ -4629,23 +4657,26 @@ g_socket_send_message_with_timeout (GSocket *socket,
char zero;
gint64 start_time;
- g_return_val_if_fail (G_IS_SOCKET (socket), -1);
- g_return_val_if_fail (address == NULL || G_IS_SOCKET_ADDRESS (address), -1);
- g_return_val_if_fail (num_vectors == 0 || vectors != NULL, -1);
- g_return_val_if_fail (num_messages == 0 || messages != NULL, -1);
- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
- g_return_val_if_fail (error == NULL || *error == NULL, -1);
+ if (bytes_written)
+ *bytes_written = 0;
+
+ g_return_val_if_fail (G_IS_SOCKET (socket), G_POLLABLE_RETURN_FAILED);
+ g_return_val_if_fail (address == NULL || G_IS_SOCKET_ADDRESS (address), G_POLLABLE_RETURN_FAILED);
+ g_return_val_if_fail (num_vectors == 0 || vectors != NULL, G_POLLABLE_RETURN_FAILED);
+ g_return_val_if_fail (num_messages == 0 || messages != NULL, G_POLLABLE_RETURN_FAILED);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_POLLABLE_RETURN_FAILED);
+ g_return_val_if_fail (error == NULL || *error == NULL, G_POLLABLE_RETURN_FAILED);
start_time = g_get_monotonic_time ();
if (!check_socket (socket, error))
- return -1;
+ return G_POLLABLE_RETURN_FAILED;
if (!check_timeout (socket, error))
- return -1;
+ return G_POLLABLE_RETURN_FAILED;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
- return -1;
+ return G_POLLABLE_RETURN_FAILED;
if (num_vectors == -1)
{
@@ -4681,7 +4712,7 @@ g_socket_send_message_with_timeout (GSocket *socket,
GError *child_error = NULL;
output_message.address = address;
- output_message.vectors = vectors;
+ output_message.vectors = (GOutputVector *) vectors;
output_message.num_vectors = num_vectors;
output_message.bytes_sent = 0;
output_message.control_messages = messages;
@@ -4692,7 +4723,7 @@ g_socket_send_message_with_timeout (GSocket *socket,
if (child_error != NULL)
{
g_propagate_error (error, child_error);
- return -1;
+ return G_POLLABLE_RETURN_FAILED;
}
while (1)
@@ -4705,24 +4736,30 @@ g_socket_send_message_with_timeout (GSocket *socket,
if (errsv == EINTR)
continue;
- if (timeout != 0 &&
- (errsv == EWOULDBLOCK ||
- errsv == EAGAIN))
+ if (errsv == EWOULDBLOCK || errsv == EAGAIN)
{
- if (!block_on_timeout (socket, G_IO_OUT, timeout, start_time,
- cancellable, error))
- return -1;
+ if (timeout != 0)
+ {
+ if (!block_on_timeout (socket, G_IO_OUT, timeout, start_time,
+ cancellable, error))
+ return G_POLLABLE_RETURN_FAILED;
- continue;
+ continue;
+ }
+
+ return G_POLLABLE_RETURN_WOULD_BLOCK;
}
- socket_set_error_lazy (error, errsv, _("Error sending message: %s"));
- return -1;
+ socket_set_error_lazy (error, errsv, _("Error sending message: %s"));
+ return G_POLLABLE_RETURN_FAILED;
}
break;
}
- return result;
+ if (bytes_written)
+ *bytes_written = result;
+
+ return G_POLLABLE_RETURN_OK;
}
#else
{
@@ -4741,7 +4778,7 @@ g_socket_send_message_with_timeout (GSocket *socket,
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("GSocketControlMessage not supported on Windows"));
- return -1;
+ return G_POLLABLE_RETURN_FAILED;
}
/* iov */
@@ -4758,7 +4795,7 @@ g_socket_send_message_with_timeout (GSocket *socket,
{
addrlen = g_socket_address_get_native_size (address);
if (!g_socket_address_to_native (address, &addr, sizeof addr, error))
- return -1;
+ return G_POLLABLE_RETURN_FAILED;
}
while (1)
@@ -4790,19 +4827,23 @@ g_socket_send_message_with_timeout (GSocket *socket,
{
if (!block_on_timeout (socket, G_IO_OUT, timeout,
start_time, cancellable, error))
- return -1;
+ return G_POLLABLE_RETURN_FAILED;
continue;
}
+
+ return G_POLLABLE_RETURN_WOULD_BLOCK;
}
socket_set_error_lazy (error, errsv, _("Error sending message: %s"));
- return -1;
+ return G_POLLABLE_RETURN_FAILED;
}
break;
}
- return bytes_sent;
+ if (bytes_written)
+ *bytes_written = bytes_sent;
+ return G_POLLABLE_RETURN_OK;
}
#endif
}
@@ -4999,14 +5040,22 @@ g_socket_send_messages_with_timeout (GSocket *socket,
{
GOutputMessage *msg = &messages[i];
GError *msg_error = NULL;
-
- result = g_socket_send_message_with_timeout (socket, msg->address,
- msg->vectors,
- msg->num_vectors,
- msg->control_messages,
- msg->num_control_messages,
- flags, wait_timeout,
- cancellable, &msg_error);
+ GPollableReturn pollable_result;
+ gsize bytes_written = 0;
+
+ pollable_result = g_socket_send_message_with_timeout (socket, msg->address,
+ msg->vectors,
+ msg->num_vectors,
+ msg->control_messages,
+ msg->num_control_messages,
+ flags, wait_timeout,
+ &bytes_written,
+ cancellable, &msg_error);
+
+ if (pollable_result == G_POLLABLE_RETURN_WOULD_BLOCK)
+ socket_set_error_lazy (&msg_error, EWOULDBLOCK, _("Error sending message: %s"));
+
+ result = pollable_result == G_POLLABLE_RETURN_OK ? bytes_written : -1;
/* check if we've timed out or how much time to wait at most */
if (timeout > 0)
diff --git a/gio/gsocket.h b/gio/gsocket.h
index a65cbc22f..30a32a84d 100644
--- a/gio/gsocket.h
+++ b/gio/gsocket.h
@@ -298,7 +298,18 @@ gssize g_socket_send_with_blocking (GSocket
gboolean blocking,
GCancellable *cancellable,
GError **error);
-
+GLIB_AVAILABLE_IN_2_60
+GPollableReturn g_socket_send_message_with_timeout (GSocket *socket,
+ GSocketAddress *address,
+ const GOutputVector *vectors,
+ gint num_vectors,
+ GSocketControlMessage **messages,
+ gint num_messages,
+ gint flags,
+ gint64 timeout,
+ gsize *bytes_written,
+ GCancellable *cancellable,
+ GError **error);
GLIB_AVAILABLE_IN_2_36
gboolean g_socket_get_option (GSocket *socket,
gint level,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]