mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-13 07:56:17 +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,
|
gint64 timeout,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
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
|
static gint
|
||||||
g_socket_send_messages_with_timeout (GSocket *socket,
|
g_socket_send_messages_with_timeout (GSocket *socket,
|
||||||
GOutputMessage *messages,
|
GOutputMessage *messages,
|
||||||
@ -4606,22 +4595,61 @@ g_socket_send_message (GSocket *socket,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
return g_socket_send_message_with_timeout (socket, address,
|
GPollableReturn res;
|
||||||
vectors, num_vectors,
|
gsize bytes_written = 0;
|
||||||
messages, num_messages, flags,
|
|
||||||
socket->priv->blocking ? -1 : 0,
|
res = g_socket_send_message_with_timeout (socket, address,
|
||||||
cancellable, error);
|
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,
|
g_socket_send_message_with_timeout (GSocket *socket,
|
||||||
GSocketAddress *address,
|
GSocketAddress *address,
|
||||||
GOutputVector *vectors,
|
const GOutputVector *vectors,
|
||||||
gint num_vectors,
|
gint num_vectors,
|
||||||
GSocketControlMessage **messages,
|
GSocketControlMessage **messages,
|
||||||
gint num_messages,
|
gint num_messages,
|
||||||
gint flags,
|
gint flags,
|
||||||
gint64 timeout,
|
gint64 timeout,
|
||||||
|
gsize *bytes_written,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -4629,23 +4657,26 @@ g_socket_send_message_with_timeout (GSocket *socket,
|
|||||||
char zero;
|
char zero;
|
||||||
gint64 start_time;
|
gint64 start_time;
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_SOCKET (socket), -1);
|
if (bytes_written)
|
||||||
g_return_val_if_fail (address == NULL || G_IS_SOCKET_ADDRESS (address), -1);
|
*bytes_written = 0;
|
||||||
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 (G_IS_SOCKET (socket), G_POLLABLE_RETURN_FAILED);
|
||||||
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
|
g_return_val_if_fail (address == NULL || G_IS_SOCKET_ADDRESS (address), G_POLLABLE_RETURN_FAILED);
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, -1);
|
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 ();
|
start_time = g_get_monotonic_time ();
|
||||||
|
|
||||||
if (!check_socket (socket, error))
|
if (!check_socket (socket, error))
|
||||||
return -1;
|
return G_POLLABLE_RETURN_FAILED;
|
||||||
|
|
||||||
if (!check_timeout (socket, error))
|
if (!check_timeout (socket, error))
|
||||||
return -1;
|
return G_POLLABLE_RETURN_FAILED;
|
||||||
|
|
||||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||||
return -1;
|
return G_POLLABLE_RETURN_FAILED;
|
||||||
|
|
||||||
if (num_vectors == -1)
|
if (num_vectors == -1)
|
||||||
{
|
{
|
||||||
@ -4681,7 +4712,7 @@ g_socket_send_message_with_timeout (GSocket *socket,
|
|||||||
GError *child_error = NULL;
|
GError *child_error = NULL;
|
||||||
|
|
||||||
output_message.address = address;
|
output_message.address = address;
|
||||||
output_message.vectors = vectors;
|
output_message.vectors = (GOutputVector *) vectors;
|
||||||
output_message.num_vectors = num_vectors;
|
output_message.num_vectors = num_vectors;
|
||||||
output_message.bytes_sent = 0;
|
output_message.bytes_sent = 0;
|
||||||
output_message.control_messages = messages;
|
output_message.control_messages = messages;
|
||||||
@ -4692,7 +4723,7 @@ g_socket_send_message_with_timeout (GSocket *socket,
|
|||||||
if (child_error != NULL)
|
if (child_error != NULL)
|
||||||
{
|
{
|
||||||
g_propagate_error (error, child_error);
|
g_propagate_error (error, child_error);
|
||||||
return -1;
|
return G_POLLABLE_RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -4705,24 +4736,30 @@ g_socket_send_message_with_timeout (GSocket *socket,
|
|||||||
if (errsv == EINTR)
|
if (errsv == EINTR)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (timeout != 0 &&
|
if (errsv == EWOULDBLOCK || errsv == EAGAIN)
|
||||||
(errsv == EWOULDBLOCK ||
|
|
||||||
errsv == EAGAIN))
|
|
||||||
{
|
{
|
||||||
if (!block_on_timeout (socket, G_IO_OUT, timeout, start_time,
|
if (timeout != 0)
|
||||||
cancellable, error))
|
{
|
||||||
return -1;
|
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"));
|
socket_set_error_lazy (error, errsv, _("Error sending message: %s"));
|
||||||
return -1;
|
return G_POLLABLE_RETURN_FAILED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
if (bytes_written)
|
||||||
|
*bytes_written = result;
|
||||||
|
|
||||||
|
return G_POLLABLE_RETURN_OK;
|
||||||
}
|
}
|
||||||
#else
|
#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,
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||||
_("GSocketControlMessage not supported on Windows"));
|
_("GSocketControlMessage not supported on Windows"));
|
||||||
return -1;
|
return G_POLLABLE_RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iov */
|
/* iov */
|
||||||
@ -4758,7 +4795,7 @@ g_socket_send_message_with_timeout (GSocket *socket,
|
|||||||
{
|
{
|
||||||
addrlen = g_socket_address_get_native_size (address);
|
addrlen = g_socket_address_get_native_size (address);
|
||||||
if (!g_socket_address_to_native (address, &addr, sizeof addr, error))
|
if (!g_socket_address_to_native (address, &addr, sizeof addr, error))
|
||||||
return -1;
|
return G_POLLABLE_RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -4790,19 +4827,23 @@ g_socket_send_message_with_timeout (GSocket *socket,
|
|||||||
{
|
{
|
||||||
if (!block_on_timeout (socket, G_IO_OUT, timeout,
|
if (!block_on_timeout (socket, G_IO_OUT, timeout,
|
||||||
start_time, cancellable, error))
|
start_time, cancellable, error))
|
||||||
return -1;
|
return G_POLLABLE_RETURN_FAILED;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return G_POLLABLE_RETURN_WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_set_error_lazy (error, errsv, _("Error sending message: %s"));
|
socket_set_error_lazy (error, errsv, _("Error sending message: %s"));
|
||||||
return -1;
|
return G_POLLABLE_RETURN_FAILED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes_sent;
|
if (bytes_written)
|
||||||
|
*bytes_written = bytes_sent;
|
||||||
|
return G_POLLABLE_RETURN_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -4999,14 +5040,22 @@ g_socket_send_messages_with_timeout (GSocket *socket,
|
|||||||
{
|
{
|
||||||
GOutputMessage *msg = &messages[i];
|
GOutputMessage *msg = &messages[i];
|
||||||
GError *msg_error = NULL;
|
GError *msg_error = NULL;
|
||||||
|
GPollableReturn pollable_result;
|
||||||
|
gsize bytes_written = 0;
|
||||||
|
|
||||||
result = g_socket_send_message_with_timeout (socket, msg->address,
|
pollable_result = g_socket_send_message_with_timeout (socket, msg->address,
|
||||||
msg->vectors,
|
msg->vectors,
|
||||||
msg->num_vectors,
|
msg->num_vectors,
|
||||||
msg->control_messages,
|
msg->control_messages,
|
||||||
msg->num_control_messages,
|
msg->num_control_messages,
|
||||||
flags, wait_timeout,
|
flags, wait_timeout,
|
||||||
cancellable, &msg_error);
|
&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 */
|
/* check if we've timed out or how much time to wait at most */
|
||||||
if (timeout > 0)
|
if (timeout > 0)
|
||||||
|
@ -298,7 +298,18 @@ gssize g_socket_send_with_blocking (GSocket
|
|||||||
gboolean blocking,
|
gboolean blocking,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
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
|
GLIB_AVAILABLE_IN_2_36
|
||||||
gboolean g_socket_get_option (GSocket *socket,
|
gboolean g_socket_get_option (GSocket *socket,
|
||||||
gint level,
|
gint level,
|
||||||
|
Loading…
Reference in New Issue
Block a user