1
0
mirror of https://github.com/PurpleI2P/i2pd.git synced 2025-01-09 11:27:53 +00:00
i2pd/libi2pd/Queue.h

144 lines
2.7 KiB
C
Raw Normal View History

/*
2024-10-11 00:43:06 +00:00
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
2013-12-10 13:00:13 +00:00
#ifndef QUEUE_H__
#define QUEUE_H__
2024-10-12 21:51:26 +00:00
#include <list>
2013-12-10 13:00:13 +00:00
#include <mutex>
#include <thread>
#include <condition_variable>
2014-04-23 16:49:02 +00:00
#include <functional>
2016-08-05 18:23:54 +00:00
#include <utility>
2013-12-10 13:00:13 +00:00
namespace i2p
{
namespace util
{
template<typename Element>
class Queue
2018-01-06 03:48:51 +00:00
{
2013-12-10 13:00:13 +00:00
public:
2015-06-16 17:14:33 +00:00
void Put (Element e)
2013-12-10 13:00:13 +00:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
2024-10-12 21:51:26 +00:00
m_Queue.push_back (std::move(e));
2013-12-10 13:00:13 +00:00
m_NonEmpty.notify_one ();
}
2024-10-12 21:51:26 +00:00
void Put (std::list<Element>& list)
2015-01-23 03:00:41 +00:00
{
2024-10-12 21:51:26 +00:00
if (!list.empty ())
2018-01-06 03:48:51 +00:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
2024-10-12 21:51:26 +00:00
m_Queue.splice (m_Queue.end (), list);
2015-01-23 03:00:41 +00:00
m_NonEmpty.notify_one ();
2024-10-12 21:51:26 +00:00
}
}
2015-06-16 17:14:33 +00:00
Element GetNext ()
2013-12-10 13:00:13 +00:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
2015-06-16 17:14:33 +00:00
auto el = GetNonThreadSafe ();
2013-12-10 13:00:13 +00:00
if (!el)
{
m_NonEmpty.wait (l);
el = GetNonThreadSafe ();
2018-01-06 03:48:51 +00:00
}
2013-12-10 13:00:13 +00:00
return el;
}
2015-06-16 17:14:33 +00:00
Element GetNextWithTimeout (int usec)
2013-12-10 13:00:13 +00:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
2015-06-16 17:14:33 +00:00
auto el = GetNonThreadSafe ();
2013-12-10 13:00:13 +00:00
if (!el)
{
m_NonEmpty.wait_for (l, std::chrono::milliseconds (usec));
el = GetNonThreadSafe ();
2018-01-06 03:48:51 +00:00
}
2013-12-10 13:00:13 +00:00
return el;
}
2014-01-11 01:21:38 +00:00
2014-04-23 16:17:14 +00:00
void Wait ()
{
std::unique_lock<std::mutex> l(m_QueueMutex);
m_NonEmpty.wait (l);
}
2014-01-11 01:21:38 +00:00
bool Wait (int sec, int usec)
{
std::unique_lock<std::mutex> l(m_QueueMutex);
return m_NonEmpty.wait_for (l, std::chrono::seconds (sec) + std::chrono::milliseconds (usec)) != std::cv_status::timeout;
}
2018-01-06 03:48:51 +00:00
bool IsEmpty ()
{
2014-01-11 01:21:38 +00:00
std::unique_lock<std::mutex> l(m_QueueMutex);
return m_Queue.empty ();
}
2015-02-03 21:45:19 +00:00
2024-11-20 18:27:25 +00:00
int GetSize () const
2015-02-03 21:45:19 +00:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
return m_Queue.size ();
2018-01-06 03:48:51 +00:00
}
2015-02-03 21:45:19 +00:00
2014-07-02 17:48:45 +00:00
void WakeUp () { m_NonEmpty.notify_all (); };
2013-12-10 13:00:13 +00:00
2015-06-16 17:14:33 +00:00
Element Get ()
2013-12-10 13:00:13 +00:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
return GetNonThreadSafe ();
2018-01-06 03:48:51 +00:00
}
2013-12-10 13:00:13 +00:00
2015-06-16 17:14:33 +00:00
Element Peek ()
2014-01-11 01:21:38 +00:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
return GetNonThreadSafe (true);
2018-01-06 03:48:51 +00:00
}
2024-10-12 21:51:26 +00:00
void GetWholeQueue (std::list<Element>& queue)
2024-10-11 00:43:06 +00:00
{
if (!queue.empty ())
{
2024-10-12 21:51:26 +00:00
std::list<Element> newQueue;
2024-10-11 00:43:06 +00:00
queue.swap (newQueue);
}
{
std::unique_lock<std::mutex> l(m_QueueMutex);
m_Queue.swap (queue);
}
}
2013-12-10 13:00:13 +00:00
2024-10-11 00:43:06 +00:00
private:
2015-06-16 17:14:33 +00:00
Element GetNonThreadSafe (bool peek = false)
2013-12-10 13:00:13 +00:00
{
if (!m_Queue.empty ())
{
2015-06-16 17:14:33 +00:00
auto el = m_Queue.front ();
2014-01-11 01:21:38 +00:00
if (!peek)
2024-10-12 21:51:26 +00:00
m_Queue.pop_front ();
2013-12-10 13:00:13 +00:00
return el;
2018-01-06 03:48:51 +00:00
}
2013-12-10 13:00:13 +00:00
return nullptr;
2018-01-06 03:48:51 +00:00
}
2013-12-10 13:00:13 +00:00
private:
2024-10-12 21:51:26 +00:00
std::list<Element> m_Queue;
2024-11-20 18:27:25 +00:00
mutable std::mutex m_QueueMutex;
2013-12-10 13:00:13 +00:00
std::condition_variable m_NonEmpty;
2018-01-06 03:48:51 +00:00
};
}
}
2013-12-10 13:00:13 +00:00
#endif