mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-27 06:47:45 +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