1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2013-2019 Bareos GmbH & Co. KG
5 
6    This program is Free Software; you can redistribute it and/or
7    modify it under the terms of version three of the GNU Affero General Public
8    License as published by the Free Software Foundation and included
9    in the file LICENSE.
10 
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14    Affero General Public License for more details.
15 
16    You should have received a copy of the GNU Affero General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19    02110-1301, USA.
20 */
21 /*
22  * Marco van Wieringen, August 2013.
23  */
24 /**
25  * @file
26  * Circular buffer used for producer/consumer problem with pthread.
27  */
28 
29 
30 #define QSIZE 10 /**< # of pointers in the queue */
31 
32 class CircularBuffer {
33   int size_ = 0;
34   int next_in_ = 0;
35   int next_out_ = 0;
36   int capacity_ = 0;
37   bool flush_ = 0;
38   pthread_mutex_t lock_ = PTHREAD_MUTEX_INITIALIZER; /**< Lock the structure */
39   pthread_cond_t notfull_
40       = PTHREAD_COND_INITIALIZER; /**< Full -> not full condition */
41   pthread_cond_t notempty_
42       = PTHREAD_COND_INITIALIZER; /**< Empty -> not empty condition */
43   void** data_ = nullptr;         /**< Circular buffer of pointers */
44 
45  public:
46   CircularBuffer(int capacity = QSIZE);
47   ~CircularBuffer();
48   int init(int capacity);
49   void destroy();
50   int enqueue(void* data);
51   void* dequeue();
52   int NextSlot();
53   int flush();
full()54   bool full() { return size_ == capacity_; }
empty()55   bool empty() { return size_ == 0; }
IsFlushing()56   bool IsFlushing() { return flush_; }
capacity()57   int capacity() const { return capacity_; }
58 };
59 
60 /**
61  * Constructor
62  */
CircularBuffer(int capacity)63 inline CircularBuffer::CircularBuffer(int capacity) { init(capacity); }
64 
65 /**
66  * Destructor
67  */
~CircularBuffer()68 inline CircularBuffer::~CircularBuffer() { destroy(); }
69