File indexing completed on 2024-06-16 04:50:12
0001 /* 0002 SPDX-FileCopyrightText: 2018 Daniel Vrátil <dvratil@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 class QObject; 0010 0011 #include <QMutex> 0012 #include <QQueue> 0013 0014 #include "private/protocol_p.h" 0015 0016 #include "akonadicore_debug.h" 0017 0018 namespace Akonadi 0019 { 0020 class CommandBufferLocker; 0021 class CommandBufferNotifyBlocker; 0022 0023 class CommandBuffer 0024 { 0025 friend class CommandBufferLocker; 0026 friend class CommandBufferNotifyBlocker; 0027 0028 public: 0029 struct Command { 0030 qint64 tag; 0031 Protocol::CommandPtr command; 0032 }; 0033 0034 CommandBuffer(QObject *parent, const char *notifySlot) 0035 : mParent(parent) 0036 , mNotifySlot(notifySlot) 0037 { 0038 } 0039 0040 void enqueue(qint64 tag, const Protocol::CommandPtr &command) 0041 { 0042 mCommands.enqueue({tag, command}); 0043 if (mNotify) { 0044 const bool ok = QMetaObject::invokeMethod(mParent, mNotifySlot.constData(), Qt::QueuedConnection); 0045 Q_ASSERT(ok); 0046 Q_UNUSED(ok) 0047 } 0048 } 0049 0050 inline Command dequeue() 0051 { 0052 return mCommands.dequeue(); 0053 } 0054 0055 inline bool isEmpty() const 0056 { 0057 return mCommands.isEmpty(); 0058 } 0059 0060 inline int size() const 0061 { 0062 return mCommands.size(); 0063 } 0064 0065 private: 0066 Q_DISABLE_COPY_MOVE(CommandBuffer) 0067 0068 QObject *mParent = nullptr; 0069 QByteArray mNotifySlot; 0070 0071 QQueue<Command> mCommands; 0072 QMutex mLock; 0073 0074 bool mNotify = true; 0075 }; 0076 0077 class CommandBufferLocker 0078 { 0079 public: 0080 explicit CommandBufferLocker(CommandBuffer *buffer) 0081 : mBuffer(buffer) 0082 { 0083 relock(); 0084 } 0085 0086 ~CommandBufferLocker() 0087 { 0088 unlock(); 0089 } 0090 0091 inline void unlock() 0092 { 0093 if (mLocked) { 0094 mBuffer->mLock.unlock(); 0095 mLocked = false; 0096 } 0097 } 0098 0099 inline void relock() 0100 { 0101 if (!mLocked) { 0102 mBuffer->mLock.lock(); 0103 mLocked = true; 0104 } 0105 } 0106 0107 private: 0108 Q_DISABLE_COPY_MOVE(CommandBufferLocker) 0109 0110 CommandBuffer *mBuffer = nullptr; 0111 bool mLocked = false; 0112 }; 0113 0114 class CommandBufferNotifyBlocker 0115 { 0116 public: 0117 explicit CommandBufferNotifyBlocker(CommandBuffer *buffer) 0118 : mBuffer(buffer) 0119 { 0120 mBuffer->mNotify = false; 0121 } 0122 0123 ~CommandBufferNotifyBlocker() 0124 { 0125 unblock(); 0126 } 0127 0128 void unblock() 0129 { 0130 mBuffer->mNotify = true; 0131 } 0132 0133 private: 0134 Q_DISABLE_COPY_MOVE(CommandBufferNotifyBlocker) 0135 0136 CommandBuffer *mBuffer; 0137 }; 0138 0139 } // namespace