Akonadi

channel.h
1 /*
2  Copyright (c) 2018 Daniel Vrátil <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #ifndef AKONADIPRIVATE_CHANNEL_P_H_
21 #define AKONADIPRIVATE_CHANNEL_P_H_
22 
23 #include "akonadiprivate_export.h"
24 
25 #include <QByteArray>
26 
27 #include <boost/interprocess/managed_shared_memory.hpp>
28 #include <boost/interprocess/mapped_region.hpp>
29 #include <boost/interprocess/sync/interprocess_mutex.hpp>
30 #include <boost/interprocess/sync/interprocess_condition.hpp>
31 
32 #include <deque>
33 #include <mutex>
34 
35 namespace Akonadi {
36 
37 class ChannelBase
38 {
39 public:
40  explicit ChannelBase(const QByteArray &id);
41  ChannelBase(const ChannelBase &other) = delete;
42  ~ChannelBase() = default;
43 
44  void setCapacity(std::size_t capacity);
45  Q_REQUIRED_RESULT std::size_t capacity() const;
46 
47  ChannelBase &operator=(const ChannelBase &other) = delete;
48 
50  bool create();
52  bool attach();
53 
54 protected:
55  struct Queue {
56  boost::interprocess::interprocess_condition full;
57  boost::interprocess::interprocess_condition empty;
58  boost::interprocess::interprocess_mutex mutex;
59  std::size_t capacity;
60  };
61 
62  const QByteArray mId;
63  boost::interprocess::shared_memory_object mShm;
64  boost::interprocess::mapped_region mMapped;
65  Queue *mQueueData = nullptr;
66 }
67 
68 template<typename T>
69 class Channel : public ChannelBase
70 {
71 public:
72  explicit Channel(const QByteArray &id) = default;
73  ~Channel() = default;
74 
75  void enqueue(T &&entity)
76  {
77  Q_ASSERT(mQueueData);
78  std::unique_lock<boost::interprocess::interprocess_mutex> lock(mQueueData->mutex);
79  while (mQueue.size() >= mQueueData->capacity) {
80  mQueueData->full.wait(lock);
81  }
82  mQueue.emplace_back(entity);
83  mQueueData->empty.wake_one();
84  }
85 
86  Q_REQUIRED_RESULT T &&dequeue()
87  {
88  Q_ASSERT(mQueueData);
89  std::unique_lock<boost::interprocess::interprocess_mutex> lock(mQueueData->mutex);
90  while (mQueue.empty()) {
91  mQueueData->empty.wait(lock);
92  }
93  T elem = std::move(mQueue.front());
94  mQueue.pop();
95  mQueueData->full.wake_one();
96  return elem; // moves
97  }
98 
99 private:
100  std::deque<T> mQueue;
101 };
102 
103 } // namespace Akonadi
104 
105 #endif
KDEGAMES_EXPORT QAction * create(StandardGameAction id, const QObject *recvr, const char *slot, QObject *parent)
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jun 5 2020 23:08:54 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.