Commit 7f985b35 authored by Philip Withnall's avatar Philip Withnall

gsocket: Factor out blocking parameter from g_socket_receive_message()

This will make future API additions easier. The factored version is
internal for the time being.

https://bugzilla.gnome.org/show_bug.cgi?id=751924
parent 5d689474
......@@ -138,6 +138,17 @@ static gboolean g_socket_initable_init (GInitable *initable,
static GSocketAddress *
cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len);
static gssize
g_socket_receive_message_with_blocking (GSocket *socket,
GSocketAddress **address,
GInputVector *vectors,
gint num_vectors,
GSocketControlMessage ***messages,
gint *num_messages,
gint *flags,
gboolean blocking,
GCancellable *cancellable,
GError **error);
static gint
g_socket_send_messages_with_blocking (GSocket *socket,
GOutputMessage *messages,
......@@ -4440,96 +4451,17 @@ cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len)
return saddr;
}
/**
* g_socket_receive_message:
* @socket: a #GSocket
* @address: (out) (allow-none): a pointer to a #GSocketAddress
* pointer, or %NULL
* @vectors: (array length=num_vectors): an array of #GInputVector structs
* @num_vectors: the number of elements in @vectors, or -1
* @messages: (array length=num_messages) (allow-none): a pointer which
* may be filled with an array of #GSocketControlMessages, or %NULL
* @num_messages: a pointer which will be filled with the number of
* elements in @messages, or %NULL
* @flags: a pointer to an int containing #GSocketMsgFlags flags
* @cancellable: (allow-none): a %GCancellable or %NULL
* @error: a #GError pointer, or %NULL
*
* Receive data from a socket. This is the most complicated and
* fully-featured version of this call. For easier use, see
* g_socket_receive() and g_socket_receive_from().
*
* If @address is non-%NULL then @address will be set equal to the
* source address of the received packet.
* @address is owned by the caller.
*
* @vector must point to an array of #GInputVector structs and
* @num_vectors must be the length of this array. These structs
* describe the buffers that received data will be scattered into.
* If @num_vectors is -1, then @vectors is assumed to be terminated
* by a #GInputVector with a %NULL buffer pointer.
*
* As a special case, if @num_vectors is 0 (in which case, @vectors
* may of course be %NULL), then a single byte is received and
* discarded. This is to facilitate the common practice of sending a
* single '\0' byte for the purposes of transferring ancillary data.
*
* @messages, if non-%NULL, will be set to point to a newly-allocated
* array of #GSocketControlMessage instances or %NULL if no such
* messages was received. These correspond to the control messages
* received from the kernel, one #GSocketControlMessage per message
* from the kernel. This array is %NULL-terminated and must be freed
* by the caller using g_free() after calling g_object_unref() on each
* element. If @messages is %NULL, any control messages received will
* be discarded.
*
* @num_messages, if non-%NULL, will be set to the number of control
* messages received.
*
* If both @messages and @num_messages are non-%NULL, then
* @num_messages gives the number of #GSocketControlMessage instances
* in @messages (ie: not including the %NULL terminator).
*
* @flags is an in/out parameter. The commonly available arguments
* for this are available in the #GSocketMsgFlags enum, but the
* values there are the same as the system values, and the flags
* are passed in as-is, so you can pass in system-specific flags too
* (and g_socket_receive_message() may pass system-specific flags out).
* Flags passed in to the parameter affect the receive operation; flags returned
* out of it are relevant to the specific returned message.
*
* As with g_socket_receive(), data may be discarded if @socket is
* %G_SOCKET_TYPE_DATAGRAM or %G_SOCKET_TYPE_SEQPACKET and you do not
* provide enough buffer space to read a complete message. You can pass
* %G_SOCKET_MSG_PEEK in @flags to peek at the current message without
* removing it from the receive queue, but there is no portable way to find
* out the length of the message other than by reading it into a
* sufficiently-large buffer.
*
* If the socket is in blocking mode the call will block until there
* is some data to receive, the connection is closed, or there is an
* error. If there is no data available and the socket is in
* non-blocking mode, a %G_IO_ERROR_WOULD_BLOCK error will be
* returned. To be notified when data is available, wait for the
* %G_IO_IN condition.
*
* On error -1 is returned and @error is set accordingly.
*
* Returns: Number of bytes read, or 0 if the connection was closed by
* the peer, or -1 on error
*
* Since: 2.22
*/
gssize
g_socket_receive_message (GSocket *socket,
GSocketAddress **address,
GInputVector *vectors,
gint num_vectors,
GSocketControlMessage ***messages,
gint *num_messages,
gint *flags,
GCancellable *cancellable,
GError **error)
static gssize
g_socket_receive_message_with_blocking (GSocket *socket,
GSocketAddress **address,
GInputVector *vectors,
gint num_vectors,
GSocketControlMessage ***messages,
gint *num_messages,
gint *flags,
gboolean blocking,
GCancellable *cancellable,
GError **error)
{
GInputVector one_vector;
char one_byte;
......@@ -4605,7 +4537,7 @@ g_socket_receive_message (GSocket *socket,
if (errsv == EINTR)
continue;
if (socket->priv->blocking &&
if (blocking &&
(errsv == EWOULDBLOCK ||
errsv == EAGAIN))
{
......@@ -4679,7 +4611,7 @@ g_socket_receive_message (GSocket *socket,
{
win32_unset_event_mask (socket, FD_READ);
if (socket->priv->blocking)
if (blocking)
{
if (!g_socket_condition_wait (socket,
G_IO_IN, cancellable, error))
......@@ -4716,6 +4648,104 @@ g_socket_receive_message (GSocket *socket,
#endif
}
/**
* g_socket_receive_message:
* @socket: a #GSocket
* @address: (out) (allow-none): a pointer to a #GSocketAddress
* pointer, or %NULL
* @vectors: (array length=num_vectors): an array of #GInputVector structs
* @num_vectors: the number of elements in @vectors, or -1
* @messages: (array length=num_messages) (allow-none): a pointer which
* may be filled with an array of #GSocketControlMessages, or %NULL
* @num_messages: a pointer which will be filled with the number of
* elements in @messages, or %NULL
* @flags: a pointer to an int containing #GSocketMsgFlags flags
* @cancellable: (allow-none): a %GCancellable or %NULL
* @error: a #GError pointer, or %NULL
*
* Receive data from a socket. This is the most complicated and
* fully-featured version of this call. For easier use, see
* g_socket_receive() and g_socket_receive_from().
*
* If @address is non-%NULL then @address will be set equal to the
* source address of the received packet.
* @address is owned by the caller.
*
* @vector must point to an array of #GInputVector structs and
* @num_vectors must be the length of this array. These structs
* describe the buffers that received data will be scattered into.
* If @num_vectors is -1, then @vectors is assumed to be terminated
* by a #GInputVector with a %NULL buffer pointer.
*
* As a special case, if @num_vectors is 0 (in which case, @vectors
* may of course be %NULL), then a single byte is received and
* discarded. This is to facilitate the common practice of sending a
* single '\0' byte for the purposes of transferring ancillary data.
*
* @messages, if non-%NULL, will be set to point to a newly-allocated
* array of #GSocketControlMessage instances or %NULL if no such
* messages was received. These correspond to the control messages
* received from the kernel, one #GSocketControlMessage per message
* from the kernel. This array is %NULL-terminated and must be freed
* by the caller using g_free() after calling g_object_unref() on each
* element. If @messages is %NULL, any control messages received will
* be discarded.
*
* @num_messages, if non-%NULL, will be set to the number of control
* messages received.
*
* If both @messages and @num_messages are non-%NULL, then
* @num_messages gives the number of #GSocketControlMessage instances
* in @messages (ie: not including the %NULL terminator).
*
* @flags is an in/out parameter. The commonly available arguments
* for this are available in the #GSocketMsgFlags enum, but the
* values there are the same as the system values, and the flags
* are passed in as-is, so you can pass in system-specific flags too
* (and g_socket_receive_message() may pass system-specific flags out).
* Flags passed in to the parameter affect the receive operation; flags returned
* out of it are relevant to the specific returned message.
*
* As with g_socket_receive(), data may be discarded if @socket is
* %G_SOCKET_TYPE_DATAGRAM or %G_SOCKET_TYPE_SEQPACKET and you do not
* provide enough buffer space to read a complete message. You can pass
* %G_SOCKET_MSG_PEEK in @flags to peek at the current message without
* removing it from the receive queue, but there is no portable way to find
* out the length of the message other than by reading it into a
* sufficiently-large buffer.
*
* If the socket is in blocking mode the call will block until there
* is some data to receive, the connection is closed, or there is an
* error. If there is no data available and the socket is in
* non-blocking mode, a %G_IO_ERROR_WOULD_BLOCK error will be
* returned. To be notified when data is available, wait for the
* %G_IO_IN condition.
*
* On error -1 is returned and @error is set accordingly.
*
* Returns: Number of bytes read, or 0 if the connection was closed by
* the peer, or -1 on error
*
* Since: 2.22
*/
gssize
g_socket_receive_message (GSocket *socket,
GSocketAddress **address,
GInputVector *vectors,
gint num_vectors,
GSocketControlMessage ***messages,
gint *num_messages,
gint *flags,
GCancellable *cancellable,
GError **error)
{
return g_socket_receive_message_with_blocking (socket, address, vectors,
num_vectors, messages,
num_messages, flags,
socket->priv->blocking,
cancellable, error);
}
/**
* g_socket_get_credentials:
* @socket: a #GSocket.
......
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