Adding support for in-place use of ProducerConsumerQueue.
[folly.git] / folly / docs / ProducerConsumerQueue.md
1 `folly/ProducerConsumerQueue.h`
2 -------------------------------
3
4 The `folly::ProducerConsumerQueue` class is a one-producer
5 one-consumer queue with very low synchronization overhead.
6
7 The queue must be created with a fixed maximum size (and allocates
8 that many cells of sizeof(T)), and it provides just a few simple
9 operations:
10
11  * `read`: Attempt to read the value at the front to the queue into a variable,
12            returns `false` iff queue was empty.
13  * `write`: Emplace a value at the end of the queue, returns `false` iff the
14             queue was full.
15  * `frontPtr`: Retrieve a pointer to the item at the front of the queue, or
16                `nullptr` if it is empty.
17  * `popFront`: Remove the item from the front of the queue (queue must not be
18                empty).
19  * `isEmpty`: Check if the queue is empty.
20  * `isFull`: Check if the queue is full.
21
22 All of these operations are wait-free.  The read operations (including
23 `frontPtr` and `popFront`) and write operations must only be called by the
24 reader and writer thread, respectively. `isFull` and `isEmpty` may be called by
25 either thread, but the return values from `read`, `write`, or `frontPtr` are
26 sufficient for most cases.
27
28 `write` may fail if the queue is full, and `read` may fail if the queue is
29 empty, so in many situations it is important to choose the queue size such that
30 the queue filling  or staying empty for long is unlikely.
31
32 ### Example
33 ***
34
35 A toy example that doesn't really do anything useful:
36
37 ``` Cpp
38     folly::ProducerConsumerQueue<folly::fbstring> queue;
39
40     std::thread reader([&queue] {
41       for (;;) {
42         folly::fbstring str;
43         while (!queue.read(str)) {
44           //spin until we get a value
45           continue;
46         }
47
48         sink(str);
49       }
50     });
51
52     // producer thread:
53     for (;;) {
54       folly::fbstring str = source();
55       while (!queue.write(str)) {
56         //spin until the queue has room
57         continue;
58       }
59     }
60 ```
61
62 Alternatively, the consumer may be written as follows to use the 'front' value
63 in place, thus avoiding moves or copies:
64
65 ``` Cpp
66     std::thread reader([&queue] {
67       for (;;) {
68         folly::fbstring* pval;
69         do {
70           pval = queue.frontPtr();
71         } while (!pval); // spin until we get a value;
72
73         sink(*pval);
74         queue.popFront();
75       }
76     });
77 ```