mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-26 14:37:44 +00:00
Added a thread secure blocking queue
This commit is contained in:
parent
0d10a4fdfd
commit
bfd3cbac3c
1 changed files with 98 additions and 0 deletions
98
src/servers/Server_Common/Util/LockedWaitQueue.h
Normal file
98
src/servers/Server_Common/Util/LockedWaitQueue.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
#ifndef _LOCKED_WAIT_H
|
||||
#define _LOCKED_WAIT_H
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <atomic>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
||||
template< typename T >
|
||||
class LockedWaitQueue
|
||||
{
|
||||
private:
|
||||
std::mutex m_queueLock;
|
||||
std::queue< T > m_queue;
|
||||
std::condition_variable m_condition;
|
||||
std::atomic<bool> m_shutdown;
|
||||
|
||||
public:
|
||||
|
||||
LockedWaitQueue<T>() : m_shutdown(false) { }
|
||||
|
||||
void push( const T& value )
|
||||
{
|
||||
std::lock_guard< std::mutex > lock( m_queueLock );
|
||||
m_queue.push( std::move( value ) );
|
||||
|
||||
m_condition.notify_one();
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
std::lock_guard< std::mutex > lock( m_queueLock );
|
||||
|
||||
return _queue.empty();
|
||||
}
|
||||
|
||||
bool pop( T& value )
|
||||
{
|
||||
std::lock_guard< std::mutex > lock( m_queueLock );
|
||||
|
||||
if( m_queue.empty() || m_shutdown )
|
||||
return false;
|
||||
|
||||
value = m_queue.front();
|
||||
|
||||
m_queue.pop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void waitAndPop( T& value )
|
||||
{
|
||||
std::unique_lock< std::mutex > lock( m_queueLock );
|
||||
|
||||
while( m_queue.empty() && !m_shutdown )
|
||||
m_condition.wait(lock);
|
||||
|
||||
if( m_queue.empty() || m_shutdown )
|
||||
return;
|
||||
|
||||
value = m_queue.front();
|
||||
|
||||
m_queue.pop();
|
||||
}
|
||||
|
||||
void cancel()
|
||||
{
|
||||
std::unique_lock< std::mutex > lock( m_queueLock );
|
||||
|
||||
while( !m_queue.empty() )
|
||||
{
|
||||
T& value = m_queue.front();
|
||||
|
||||
deleteQueuedObject( value );
|
||||
|
||||
m_queue.pop();
|
||||
}
|
||||
|
||||
_shutdown = true;
|
||||
|
||||
_condition.notify_all();
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename E = T >
|
||||
typename std::enable_if<std::is_pointer<E>::value>::type deleteQueuedObject( E& obj ) { delete obj; }
|
||||
|
||||
template< typename E = T >
|
||||
typename std::enable_if<!std::is_pointer<E>::value>::type deleteQueuedObject( E const& ) { }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Add table
Reference in a new issue