]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/doc/nonblocking.qbk
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / fiber / doc / nonblocking.qbk
1 [/
2 Copyright Oliver Kowalke, Nat Goodspeed 2015.
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt
6 ]
7
8 [/ import path is relative to this .qbk file]
9 [import ../examples/adapt_nonblocking.cpp]
10
11 [#nonblocking]
12 [section:nonblocking Integrating Fibers with Nonblocking I/O]
13
14 [heading Overview]
15
16 ['Nonblocking] I/O is distinct from ['asynchronous] I/O. A true async I/O
17 operation promises to initiate the operation and notify the caller on
18 completion, usually via some sort of callback (as described in [link callbacks
19 Integrating Fibers with Asynchronous Callbacks]).
20
21 In contrast, a nonblocking I/O operation refuses to start at all if it would
22 be necessary to block, returning an error code such as
23 [@http://man7.org/linux/man-pages/man3/errno.3.html `EWOULDBLOCK`]. The
24 operation is performed only when it can complete immediately. In effect, the
25 caller must repeatedly retry the operation until it stops returning
26 `EWOULDBLOCK`.
27
28 In a classic event-driven program, it can be something of a headache to use
29 nonblocking I/O. At the point where the nonblocking I/O is attempted, a return
30 value of `EWOULDBLOCK` requires the caller to pass control back to the main
31 event loop, arranging to retry again on the next iteration.
32
33 Worse, a nonblocking I/O operation might ['partially] succeed. That means that
34 the relevant business logic must continue receiving control on every main loop
35 iteration until all required data have been processed: a doubly-nested loop,
36 implemented as a callback-driven state machine.
37
38 __boost_fiber__ can simplify this problem immensely. Once you have integrated
39 with the application's main loop as described in [link integration Sharing a
40 Thread with Another Main Loop], waiting for the next main-loop iteration is as
41 simple as calling [ns_function_link this_fiber..yield].
42
43 [heading Example Nonblocking API]
44
45 For purposes of illustration, consider this API:
46
47 [NonblockingAPI]
48
49 [heading Polling for Completion]
50
51 We can build a low-level wrapper around `NonblockingAPI::read()` that
52 shields its caller from ever having to deal with `EWOULDBLOCK`:
53
54 [nonblocking_read_chunk]
55
56 [heading Filling All Desired Data]
57
58 Given `read_chunk()`, we can straightforwardly iterate until we have all
59 desired data:
60
61 [nonblocking_read_desired]
62
63 (Of ['course] there are more efficient ways to accumulate string data. That's
64 not the point of this example.)
65
66 [heading Wrapping it Up]
67
68 Finally, we can define a relevant exception:
69
70 [nonblocking_IncompleteRead]
71
72 and write a simple `read()` function that either returns all desired data or
73 throws `IncompleteRead`:
74
75 [nonblocking_read]
76
77 Once we can transparently wait for the next main-loop iteration using
78 [ns_function_link this_fiber..yield], ordinary encapsulation Just Works.
79
80 [/ @path link is relative to (eventual) doc/html/index.html, hence ../..]
81 The source code above is found in
82 [@../../examples/adapt_nonblocking.cpp adapt_nonblocking.cpp].
83
84 [endsect]