mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
Add g_socket_send_message_with_timeout()
This commit is contained in:
parent
63ea8d18f3
commit
f0a11b2727
151
gio/gsocket.c
151
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;
|
||||
GPollableReturn pollable_result;
|
||||
gsize bytes_written = 0;
|
||||
|
||||
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);
|
||||
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)
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user