nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* GIO - GLib Input, Output and Streaming Library
2 *
3 * Copyright 2015 Collabora Ltd.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Philip Withnall <philip.withnall@collabora.co.uk>
19 */
20  
21 #include "config.h"
22  
23 #include "gdatagrambased.h"
24  
25 #include "gcancellable.h"
26 #include "gioenumtypes.h"
27 #include "gioerror.h"
28 #include "gnetworkingprivate.h"
29 #include "gsocketaddress.h"
30 #include "glibintl.h"
31  
32 /**
33 * SECTION:gdatagrambased
34 * @short_description: Low-level datagram communications interface
35 * @include: gio/gio.h
36 * @see_also: #GSocket, [<gnetworking.h>][gio-gnetworking.h]
37 *
38 * A #GDatagramBased is a networking interface for representing datagram-based
39 * communications. It is a more or less direct mapping of the core parts of the
40 * BSD socket API in a portable GObject interface. It is implemented by
41 * #GSocket, which wraps the UNIX socket API on UNIX and winsock2 on Windows.
42 *
43 * #GDatagramBased is entirely platform independent, and is intended to be used
44 * alongside higher-level networking APIs such as #GIOStream.
45 *
46 * It uses vectored scatter/gather I/O by default, allowing for many messages
47 * to be sent or received in a single call. Where possible, implementations of
48 * the interface should take advantage of vectored I/O to minimise processing
49 * or system calls. For example, #GSocket uses recvmmsg() and sendmmsg() where
50 * possible. Callers should take advantage of scatter/gather I/O (the use of
51 * multiple buffers per message) to avoid unnecessary copying of data to
52 * assemble or disassemble a message.
53 *
54 * Each #GDatagramBased operation has a timeout parameter which may be negative
55 * for blocking behaviour, zero for non-blocking behaviour, or positive for
56 * timeout behaviour. A blocking operation blocks until finished or there is an
57 * error. A non-blocking operation will return immediately with a
58 * %G_IO_ERROR_WOULD_BLOCK error if it cannot make progress. A timeout operation
59 * will block until the operation is complete or the timeout expires; if the
60 * timeout expires it will return what progress it made, or
61 * %G_IO_ERROR_TIMED_OUT if no progress was made. To know when a call would
62 * successfully run you can call g_datagram_based_condition_check() or
63 * g_datagram_based_condition_wait(). You can also use
64 * g_datagram_based_create_source() and attach it to a #GMainContext to get
65 * callbacks when I/O is possible.
66 *
67 * When running a non-blocking operation applications should always be able to
68 * handle getting a %G_IO_ERROR_WOULD_BLOCK error even when some other function
69 * said that I/O was possible. This can easily happen in case of a race
70 * condition in the application, but it can also happen for other reasons. For
71 * instance, on Windows a socket is always seen as writable until a write
72 * returns %G_IO_ERROR_WOULD_BLOCK.
73 *
74 * As with #GSocket, #GDatagramBaseds can be either connection oriented or
75 * connectionless. The interface does not cover connection establishment — use
76 * methods on the underlying type to establish a connection before sending and
77 * receiving data through the #GDatagramBased API. For connectionless socket
78 * types the target/source address is specified or received in each I/O
79 * operation.
80 *
81 * Like most other APIs in GLib, #GDatagramBased is not inherently thread safe.
82 * To use a #GDatagramBased concurrently from multiple threads, you must
83 * implement your own locking.
84 *
85 * Since: 2.48
86 */
87  
88 G_DEFINE_INTERFACE (GDatagramBased, g_datagram_based, G_TYPE_OBJECT)
89  
90 static void
91 g_datagram_based_default_init (GDatagramBasedInterface *iface)
92 {
93 /* Nothing here. */
94 }
95  
96 /**
97 * g_datagram_based_receive_messages:
98 * @datagram_based: a #GDatagramBased
99 * @messages: (array length=num_messages): an array of #GInputMessage structs
100 * @num_messages: the number of elements in @messages
101 * @flags: an int containing #GSocketMsgFlags flags for the overall operation
102 * @timeout: the maximum time (in microseconds) to wait, 0 to not block, or -1
103 * to block indefinitely
104 * @cancellable: (allow-none): a %GCancellable
105 * @error: return location for a #GError
106 *
107 * Receive one or more data messages from @datagram_based in one go.
108 *
109 * @messages must point to an array of #GInputMessage structs and
110 * @num_messages must be the length of this array. Each #GInputMessage
111 * contains a pointer to an array of #GInputVector structs describing the
112 * buffers that the data received in each message will be written to.
113 *
114 * @flags modify how all messages are received. The commonly available
115 * arguments for this are available in the #GSocketMsgFlags enum, but the
116 * values there are the same as the system values, and the flags
117 * are passed in as-is, so you can pass in system-specific flags too. These
118 * flags affect the overall receive operation. Flags affecting individual
119 * messages are returned in #GInputMessage.flags.
120 *
121 * The other members of #GInputMessage are treated as described in its
122 * documentation.
123 *
124 * If @timeout is negative the call will block until @num_messages have been
125 * received, the connection is closed remotely (EOS), @cancellable is cancelled,
126 * or an error occurs.
127 *
128 * If @timeout is 0 the call will return up to @num_messages without blocking,
129 * or %G_IO_ERROR_WOULD_BLOCK if no messages are queued in the operating system
130 * to be received.
131 *
132 * If @timeout is positive the call will block on the same conditions as if
133 * @timeout were negative. If the timeout is reached
134 * before any messages are received, %G_IO_ERROR_TIMED_OUT is returned,
135 * otherwise it will return the number of messages received before timing out.
136 * (Note: This is effectively the behaviour of `MSG_WAITFORONE` with
137 * recvmmsg().)
138 *
139 * To be notified when messages are available, wait for the %G_IO_IN condition.
140 * Note though that you may still receive %G_IO_ERROR_WOULD_BLOCK from
141 * g_datagram_based_receive_messages() even if you were previously notified of a
142 * %G_IO_IN condition.
143 *
144 * If the remote peer closes the connection, any messages queued in the
145 * underlying receive buffer will be returned, and subsequent calls to
146 * g_datagram_based_receive_messages() will return 0 (with no error set).
147 *
148 * If the connection is shut down or closed (by calling g_socket_close() or
149 * g_socket_shutdown() with @shutdown_read set, if it’s a #GSocket, for
150 * example), all calls to this function will return %G_IO_ERROR_CLOSED.
151 *
152 * On error -1 is returned and @error is set accordingly. An error will only
153 * be returned if zero messages could be received; otherwise the number of
154 * messages successfully received before the error will be returned. If
155 * @cancellable is cancelled, %G_IO_ERROR_CANCELLED is returned as with any
156 * other error.
157 *
158 * Returns: number of messages received, or -1 on error. Note that the number
159 * of messages received may be smaller than @num_messages if @timeout is
160 * zero or positive, if the peer closed the connection, or if @num_messages
161 * was larger than `UIO_MAXIOV` (1024), in which case the caller may re-try
162 * to receive the remaining messages.
163 *
164 * Since: 2.48
165 */
166 gint
167 g_datagram_based_receive_messages (GDatagramBased *datagram_based,
168 GInputMessage *messages,
169 guint num_messages,
170 gint flags,
171 gint64 timeout,
172 GCancellable *cancellable,
173 GError **error)
174 {
175 GDatagramBasedInterface *iface;
176 gint retval;
177 GError *child_error = NULL;
178  
179 g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), -1);
180 g_return_val_if_fail (num_messages == 0 || messages != NULL, -1);
181 g_return_val_if_fail (cancellable == NULL ||
182 G_IS_CANCELLABLE (cancellable), -1);
183 g_return_val_if_fail (error == NULL || *error == NULL, -1);
184  
185 iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
186 g_assert (iface->receive_messages != NULL);
187  
188 retval = iface->receive_messages (datagram_based, messages, num_messages,
189 flags, timeout, cancellable, &child_error);
190  
191 /* Postconditions. */
192 g_return_val_if_fail ((retval < 0) == (child_error != NULL), -1);
193 g_return_val_if_fail (timeout == 0 ||
194 !g_error_matches (child_error, G_IO_ERROR,
195 G_IO_ERROR_WOULD_BLOCK), -1);
196 g_return_val_if_fail (timeout > 0 ||
197 !g_error_matches (child_error, G_IO_ERROR,
198 G_IO_ERROR_TIMED_OUT), -1);
199 g_return_val_if_fail (retval < 0 || (guint) retval <= num_messages, -1);
200  
201 if (child_error != NULL)
202 g_propagate_error (error, child_error);
203  
204 return retval;
205 }
206  
207 /**
208 * g_datagram_based_send_messages:
209 * @datagram_based: a #GDatagramBased
210 * @messages: (array length=num_messages): an array of #GOutputMessage structs
211 * @num_messages: the number of elements in @messages
212 * @flags: an int containing #GSocketMsgFlags flags
213 * @timeout: the maximum time (in microseconds) to wait, 0 to not block, or -1
214 * to block indefinitely
215 * @cancellable: (nullable): a %GCancellable
216 * @error: return location for a #GError
217 *
218 * Send one or more data messages from @datagram_based in one go.
219 *
220 * @messages must point to an array of #GOutputMessage structs and
221 * @num_messages must be the length of this array. Each #GOutputMessage
222 * contains an address to send the data to, and a pointer to an array of
223 * #GOutputVector structs to describe the buffers that the data to be sent
224 * for each message will be gathered from.
225 *
226 * @flags modify how the message is sent. The commonly available arguments
227 * for this are available in the #GSocketMsgFlags enum, but the
228 * values there are the same as the system values, and the flags
229 * are passed in as-is, so you can pass in system-specific flags too.
230 *
231 * The other members of #GOutputMessage are treated as described in its
232 * documentation.
233 *
234 * If @timeout is negative the call will block until @num_messages have been
235 * sent, @cancellable is cancelled, or an error occurs.
236 *
237 * If @timeout is 0 the call will send up to @num_messages without blocking,
238 * or will return %G_IO_ERROR_WOULD_BLOCK if there is no space to send messages.
239 *
240 * If @timeout is positive the call will block on the same conditions as if
241 * @timeout were negative. If the timeout is reached before any messages are
242 * sent, %G_IO_ERROR_TIMED_OUT is returned, otherwise it will return the number
243 * of messages sent before timing out.
244 *
245 * To be notified when messages can be sent, wait for the %G_IO_OUT condition.
246 * Note though that you may still receive %G_IO_ERROR_WOULD_BLOCK from
247 * g_datagram_based_send_messages() even if you were previously notified of a
248 * %G_IO_OUT condition. (On Windows in particular, this is very common due to
249 * the way the underlying APIs work.)
250 *
251 * If the connection is shut down or closed (by calling g_socket_close() or
252 * g_socket_shutdown() with @shutdown_write set, if it’s a #GSocket, for
253 * example), all calls to this function will return %G_IO_ERROR_CLOSED.
254 *
255 * On error -1 is returned and @error is set accordingly. An error will only
256 * be returned if zero messages could be sent; otherwise the number of messages
257 * successfully sent before the error will be returned. If @cancellable is
258 * cancelled, %G_IO_ERROR_CANCELLED is returned as with any other error.
259 *
260 * Returns: number of messages sent, or -1 on error. Note that the number of
261 * messages sent may be smaller than @num_messages if @timeout is zero
262 * or positive, or if @num_messages was larger than `UIO_MAXIOV` (1024), in
263 * which case the caller may re-try to send the remaining messages.
264 *
265 * Since: 2.48
266 */
267 gint
268 g_datagram_based_send_messages (GDatagramBased *datagram_based,
269 GOutputMessage *messages,
270 guint num_messages,
271 gint flags,
272 gint64 timeout,
273 GCancellable *cancellable,
274 GError **error)
275 {
276 GDatagramBasedInterface *iface;
277 gint retval;
278 GError *child_error = NULL;
279  
280 g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), -1);
281 g_return_val_if_fail (num_messages == 0 || messages != NULL, -1);
282 g_return_val_if_fail (cancellable == NULL ||
283 G_IS_CANCELLABLE (cancellable), -1);
284 g_return_val_if_fail (error == NULL || *error == NULL, -1);
285  
286 iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
287 g_assert (iface->send_messages != NULL);
288  
289 retval = iface->send_messages (datagram_based, messages, num_messages, flags,
290 timeout, cancellable, &child_error);
291  
292 /* Postconditions. */
293 g_return_val_if_fail ((retval < 0) == (child_error != NULL), -1);
294 g_return_val_if_fail (timeout == 0 ||
295 !g_error_matches (child_error, G_IO_ERROR,
296 G_IO_ERROR_WOULD_BLOCK), -1);
297 g_return_val_if_fail (timeout > 0 ||
298 !g_error_matches (child_error, G_IO_ERROR,
299 G_IO_ERROR_TIMED_OUT), -1);
300 g_return_val_if_fail (retval < 0 || (guint) retval <= num_messages, -1);
301 g_return_val_if_fail (!(timeout < 0 && num_messages > 0) || retval != 0, -1);
302  
303 if (child_error != NULL)
304 g_propagate_error (error, child_error);
305  
306 return retval;
307 }
308  
309 /**
310 * g_datagram_based_create_source:
311 * @datagram_based: a #GDatagramBased
312 * @condition: a #GIOCondition mask to monitor
313 * @cancellable: (nullable): a #GCancellable
314 *
315 * Creates a #GSource that can be attached to a #GMainContext to monitor for
316 * the availability of the specified @condition on the #GDatagramBased. The
317 * #GSource keeps a reference to the @datagram_based.
318 *
319 * The callback on the source is of the #GDatagramBasedSourceFunc type.
320 *
321 * It is meaningless to specify %G_IO_ERR or %G_IO_HUP in @condition; these
322 * conditions will always be reported in the callback if they are true.
323 *
324 * If non-%NULL, @cancellable can be used to cancel the source, which will
325 * cause the source to trigger, reporting the current condition (which is
326 * likely 0 unless cancellation happened at the same time as a condition
327 * change). You can check for this in the callback using
328 * g_cancellable_is_cancelled().
329 *
330 * Returns: (transfer full): a newly allocated #GSource
331 *
332 * Since: 2.48
333 */
334 GSource *
335 g_datagram_based_create_source (GDatagramBased *datagram_based,
336 GIOCondition condition,
337 GCancellable *cancellable)
338 {
339 GDatagramBasedInterface *iface;
340  
341 g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), NULL);
342 g_return_val_if_fail (cancellable == NULL ||
343 G_IS_CANCELLABLE (cancellable), NULL);
344  
345 iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
346 g_assert (iface->create_source != NULL);
347  
348 return iface->create_source (datagram_based, condition, cancellable);
349 }
350  
351 /**
352 * g_datagram_based_condition_check:
353 * @datagram_based: a #GDatagramBased
354 * @condition: a #GIOCondition mask to check
355 *
356 * Checks on the readiness of @datagram_based to perform operations. The
357 * operations specified in @condition are checked for and masked against the
358 * currently-satisfied conditions on @datagram_based. The result is returned.
359 *
360 * %G_IO_IN will be set in the return value if data is available to read with
361 * g_datagram_based_receive_messages(), or if the connection is closed remotely
362 * (EOS); and if the datagram_based has not been closed locally using some
363 * implementation-specific method (such as g_socket_close() or
364 * g_socket_shutdown() with @shutdown_read set, if it’s a #GSocket).
365 *
366 * If the connection is shut down or closed (by calling g_socket_close() or
367 * g_socket_shutdown() with @shutdown_read set, if it’s a #GSocket, for
368 * example), all calls to this function will return %G_IO_ERROR_CLOSED.
369 *
370 * %G_IO_OUT will be set if it is expected that at least one byte can be sent
371 * using g_datagram_based_send_messages() without blocking. It will not be set
372 * if the datagram_based has been closed locally.
373 *
374 * %G_IO_HUP will be set if the connection has been closed locally.
375 *
376 * %G_IO_ERR will be set if there was an asynchronous error in transmitting data
377 * previously enqueued using g_datagram_based_send_messages().
378 *
379 * Note that on Windows, it is possible for an operation to return
380 * %G_IO_ERROR_WOULD_BLOCK even immediately after
381 * g_datagram_based_condition_check() has claimed that the #GDatagramBased is
382 * ready for writing. Rather than calling g_datagram_based_condition_check() and
383 * then writing to the #GDatagramBased if it succeeds, it is generally better to
384 * simply try writing right away, and try again later if the initial attempt
385 * returns %G_IO_ERROR_WOULD_BLOCK.
386 *
387 * It is meaningless to specify %G_IO_ERR or %G_IO_HUP in @condition; these
388 * conditions will always be set in the output if they are true. Apart from
389 * these flags, the output is guaranteed to be masked by @condition.
390 *
391 * This call never blocks.
392 *
393 * Returns: the #GIOCondition mask of the current state
394 *
395 * Since: 2.48
396 */
397 GIOCondition
398 g_datagram_based_condition_check (GDatagramBased *datagram_based,
399 GIOCondition condition)
400 {
401 GDatagramBasedInterface *iface;
402 GIOCondition out;
403  
404 g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), 0);
405  
406 iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
407 g_assert (iface->condition_check != NULL);
408  
409 out = iface->condition_check (datagram_based, condition);
410  
411 /* Postconditions. G_IO_OUT and G_IO_HUP are mutually exclusive. G_IO_IN and
412 * G_IO_HUP are mutually exclusive. The return value must be a subset of
413 * (condition | G_IO_ERR | G_IO_HUP). */
414 g_return_val_if_fail ((out & (G_IO_OUT | G_IO_HUP)) != (G_IO_OUT | G_IO_HUP),
415 out & ~G_IO_OUT);
416 g_return_val_if_fail ((out & (G_IO_IN | G_IO_HUP)) != (G_IO_IN | G_IO_HUP),
417 out & ~G_IO_IN);
418 g_return_val_if_fail ((out & ~(condition | G_IO_ERR | G_IO_HUP)) == 0,
419 out & (condition | G_IO_ERR | G_IO_HUP));
420  
421 return out;
422 }
423  
424 /**
425 * g_datagram_based_condition_wait:
426 * @datagram_based: a #GDatagramBased
427 * @condition: a #GIOCondition mask to wait for
428 * @timeout: the maximum time (in microseconds) to wait, 0 to not block, or -1
429 * to block indefinitely
430 * @cancellable: (nullable): a #GCancellable
431 * @error: return location for a #GError
432 *
433 * Waits for up to @timeout microseconds for condition to become true on
434 * @datagram_based. If the condition is met, %TRUE is returned.
435 *
436 * If @cancellable is cancelled before the condition is met, or if @timeout is
437 * reached before the condition is met, then %FALSE is returned and @error is
438 * set appropriately (%G_IO_ERROR_CANCELLED or %G_IO_ERROR_TIMED_OUT).
439 *
440 * Returns: %TRUE if the condition was met, %FALSE otherwise
441 *
442 * Since: 2.48
443 */
444 gboolean
445 g_datagram_based_condition_wait (GDatagramBased *datagram_based,
446 GIOCondition condition,
447 gint64 timeout,
448 GCancellable *cancellable,
449 GError **error)
450 {
451 GDatagramBasedInterface *iface;
452 gboolean out;
453 GError *child_error = NULL;
454  
455 g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), FALSE);
456 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable),
457 FALSE);
458 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
459  
460 iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based);
461 g_assert (iface->condition_wait != NULL);
462  
463 out = iface->condition_wait (datagram_based, condition, timeout,
464 cancellable, &child_error);
465  
466 /* Postconditions. */
467 g_return_val_if_fail (out == (child_error == NULL), FALSE);
468  
469 if (child_error != NULL)
470 g_propagate_error (error, child_error);
471  
472 return out;
473 }