diff options
author | Philip Withnall <philip.withnall@collabora.co.uk> | 2015-07-27 14:21:00 +0100 |
---|---|---|
committer | Philip Withnall <philip.withnall@collabora.co.uk> | 2015-10-01 13:58:44 +0100 |
commit | 7f985b35ce599a37144f852903993300e8f1f197 (patch) | |
tree | db8c51fa5782785b487a486c686ad3c9153fd43a | |
parent | 5d6894746635d19d719fbf15881dbd7fc375d77c (diff) | |
download | glib-7f985b35ce599a37144f852903993300e8f1f197.tar.gz |
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
-rw-r--r-- | gio/gsocket.c | 214 |
1 files changed, 122 insertions, 92 deletions
diff --git a/gio/gsocket.c b/gio/gsocket.c index 7a876905e..42c313ed3 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -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)) @@ -4717,6 +4649,104 @@ g_socket_receive_message (GSocket *socket, } /** + * 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. * @error: #GError for error reporting, or %NULL to ignore. |