/* * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. * Copyright (C) 2008-2016 TrinityCore * Copyright (C) 2005-2009 MaNGOS */ #ifndef LOCKEDQUEUE_H #define LOCKEDQUEUE_H #include #include template > class LockedQueue { //! Lock access to the queue. std::mutex _lock; //! Storage backing the queue. StorageType _queue; //! Cancellation flag. volatile bool _canceled; public: //! Create a LockedQueue. LockedQueue() : _canceled(false) { } //! Destroy a LockedQueue. virtual ~LockedQueue() { } //! Adds an item to the queue. void add(const T& item) { lock(); _queue.push_back(item); unlock(); } //! Adds items back to front of the queue template void readd(Iterator begin, Iterator end) { std::lock_guard lock(_lock); _queue.insert(_queue.begin(), begin, end); } //! Gets the next result in the queue, if any. bool next(T& result) { std::lock_guard lock(_lock); if (_queue.empty()) { return false; } result = _queue.front(); _queue.pop_front(); return true; } template bool next(T& result, Checker& check) { std::lock_guard lock(_lock); if (_queue.empty()) { return false; } result = _queue.front(); if (!check.Process(result)) { return false; } _queue.pop_front(); return true; } //! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false. T& peek(bool autoUnlock = false) { lock(); T& result = _queue.front(); if (autoUnlock) { unlock(); } return result; } //! Cancels the queue. void cancel() { std::lock_guard lock(_lock); _canceled = true; } //! Checks if the queue is cancelled. bool cancelled() { std::lock_guard lock(_lock); return _canceled; } //! Locks the queue for access. void lock() { this->_lock.lock(); } //! Unlocks the queue. void unlock() { this->_lock.unlock(); } ///! Calls pop_front of the queue void pop_front() { std::lock_guard lock(_lock); _queue.pop_front(); } ///! Checks if we're empty or not with locks held bool empty() { std::lock_guard lock(_lock); return _queue.empty(); } }; #endif