2017-03-23 00:59:25 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2020-12-21 15:17:52 +00:00
|
|
|
* Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
2017-03-23 00:59:25 +00:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation, either version 3 of the License, or (at your
|
|
|
|
* option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SYNC_QUEUE_H
|
|
|
|
#define SYNC_QUEUE_H
|
|
|
|
|
|
|
|
#include <mutex>
|
|
|
|
#include <queue>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Synchronized, locking queue. Safe for multiple producer/multiple consumer environments with
|
|
|
|
* nontrivial data (though bear in mind data needs to be copied in and out).
|
|
|
|
*/
|
2020-12-21 15:17:52 +00:00
|
|
|
template <typename T>
|
|
|
|
class SYNC_QUEUE
|
2017-03-23 00:59:25 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
SYNC_QUEUE()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Push a value onto the queue.
|
|
|
|
*/
|
|
|
|
void push( T const& aValue )
|
|
|
|
{
|
|
|
|
GUARD guard( m_mutex );
|
|
|
|
m_queue.push( aValue );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Move a value onto the queue. Useful for e.g. unique_ptr.
|
|
|
|
*/
|
|
|
|
void move_push( T&& aValue )
|
|
|
|
{
|
|
|
|
GUARD guard( m_mutex );
|
|
|
|
m_queue.push( std::move( aValue ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-12-21 15:17:52 +00:00
|
|
|
* Pop a value if the queue into the provided variable.
|
|
|
|
*
|
|
|
|
* If the queue is empty, the variable is not touched.
|
2017-03-24 14:09:08 +00:00
|
|
|
*
|
2020-12-21 15:17:52 +00:00
|
|
|
* @return true if a value was popped.
|
2017-03-23 00:59:25 +00:00
|
|
|
*/
|
2017-03-24 14:09:08 +00:00
|
|
|
bool pop( T& aReceiver )
|
2017-03-23 00:59:25 +00:00
|
|
|
{
|
|
|
|
GUARD guard( m_mutex );
|
|
|
|
|
|
|
|
if( m_queue.empty() )
|
|
|
|
{
|
2017-03-24 14:09:08 +00:00
|
|
|
return false;
|
2017-03-23 00:59:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-24 14:09:08 +00:00
|
|
|
aReceiver = std::move( m_queue.front() );
|
2017-03-23 00:59:25 +00:00
|
|
|
m_queue.pop();
|
2017-03-24 14:09:08 +00:00
|
|
|
return true;
|
2017-03-23 00:59:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-12-21 15:17:52 +00:00
|
|
|
* Return true if the queue is empty.
|
2017-03-23 00:59:25 +00:00
|
|
|
*/
|
|
|
|
bool empty() const
|
|
|
|
{
|
|
|
|
GUARD guard( m_mutex );
|
|
|
|
return m_queue.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the size of the queue.
|
|
|
|
*/
|
|
|
|
size_t size() const
|
|
|
|
{
|
|
|
|
GUARD guard( m_mutex );
|
|
|
|
return m_queue.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear the queue.
|
|
|
|
*/
|
|
|
|
void clear()
|
|
|
|
{
|
|
|
|
GUARD guard( m_mutex );
|
|
|
|
|
|
|
|
while( !m_queue.empty() )
|
|
|
|
{
|
|
|
|
m_queue.pop();
|
|
|
|
}
|
|
|
|
}
|
2020-12-21 15:17:52 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
typedef std::lock_guard<std::mutex> GUARD;
|
|
|
|
|
|
|
|
std::queue<T> m_queue;
|
|
|
|
mutable std::mutex m_mutex;
|
2017-03-23 00:59:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // SYNC_QUEUE_H
|