1
0
mirror of https://github.com/PurpleI2P/i2pd.git synced 2025-01-15 22:09:57 +00:00
i2pd/libi2pd/Queue.h

144 lines
2.7 KiB
C
Raw Normal View History

/*
2024-10-10 20:43:06 -04: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 08:00:13 -05:00
#ifndef QUEUE_H__
#define QUEUE_H__
2024-10-12 17:51:26 -04:00
#include <list>
2013-12-10 08:00:13 -05:00
#include <mutex>
#include <thread>
#include <condition_variable>
2014-04-23 12:49:02 -04:00
#include <functional>
2016-08-05 21:23:54 +03:00
#include <utility>
2013-12-10 08:00:13 -05:00
namespace i2p
{
namespace util
{
template<typename Element>
class Queue
2018-01-06 11:48:51 +08:00
{
2013-12-10 08:00:13 -05:00
public:
2015-06-16 13:14:33 -04:00
void Put (Element e)
2013-12-10 08:00:13 -05:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
2024-10-12 17:51:26 -04:00
m_Queue.push_back (std::move(e));
2013-12-10 08:00:13 -05:00
m_NonEmpty.notify_one ();
}
2024-10-12 17:51:26 -04:00
void Put (std::list<Element>& list)
2015-01-22 22:00:41 -05:00
{
2024-10-12 17:51:26 -04:00
if (!list.empty ())
2018-01-06 11:48:51 +08:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
2024-10-12 17:51:26 -04:00
m_Queue.splice (m_Queue.end (), list);
2015-01-22 22:00:41 -05:00
m_NonEmpty.notify_one ();
2024-10-12 17:51:26 -04:00
}
}
2015-06-16 13:14:33 -04:00
Element GetNext ()
2013-12-10 08:00:13 -05:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
2015-06-16 13:14:33 -04:00
auto el = GetNonThreadSafe ();
2013-12-10 08:00:13 -05:00
if (!el)
{
m_NonEmpty.wait (l);
el = GetNonThreadSafe ();
2018-01-06 11:48:51 +08:00
}
2013-12-10 08:00:13 -05:00
return el;
}
2015-06-16 13:14:33 -04:00
Element GetNextWithTimeout (int usec)
2013-12-10 08:00:13 -05:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
2015-06-16 13:14:33 -04:00
auto el = GetNonThreadSafe ();
2013-12-10 08:00:13 -05:00
if (!el)
{
m_NonEmpty.wait_for (l, std::chrono::milliseconds (usec));
el = GetNonThreadSafe ();
2018-01-06 11:48:51 +08:00
}
2013-12-10 08:00:13 -05:00
return el;
}
2014-01-10 20:21:38 -05:00
2014-04-23 12:17:14 -04:00
void Wait ()
{
std::unique_lock<std::mutex> l(m_QueueMutex);
m_NonEmpty.wait (l);
}
2014-01-10 20:21:38 -05: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 11:48:51 +08:00
bool IsEmpty ()
{
2014-01-10 20:21:38 -05:00
std::unique_lock<std::mutex> l(m_QueueMutex);
return m_Queue.empty ();
}
2015-02-03 16:45:19 -05:00
2024-11-20 13:27:25 -05:00
int GetSize () const
2015-02-03 16:45:19 -05:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
return m_Queue.size ();
2018-01-06 11:48:51 +08:00
}
2015-02-03 16:45:19 -05:00
2014-07-02 13:48:45 -04:00
void WakeUp () { m_NonEmpty.notify_all (); };
2013-12-10 08:00:13 -05:00
2015-06-16 13:14:33 -04:00
Element Get ()
2013-12-10 08:00:13 -05:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
return GetNonThreadSafe ();
2018-01-06 11:48:51 +08:00
}
2013-12-10 08:00:13 -05:00
2015-06-16 13:14:33 -04:00
Element Peek ()
2014-01-10 20:21:38 -05:00
{
std::unique_lock<std::mutex> l(m_QueueMutex);
return GetNonThreadSafe (true);
2018-01-06 11:48:51 +08:00
}
2024-10-12 17:51:26 -04:00
void GetWholeQueue (std::list<Element>& queue)
2024-10-10 20:43:06 -04:00
{
if (!queue.empty ())
{
2024-10-12 17:51:26 -04:00
std::list<Element> newQueue;
2024-10-10 20:43:06 -04:00
queue.swap (newQueue);
}
{
std::unique_lock<std::mutex> l(m_QueueMutex);
m_Queue.swap (queue);
}
}
2013-12-10 08:00:13 -05:00
2024-10-10 20:43:06 -04:00
private:
2015-06-16 13:14:33 -04:00
Element GetNonThreadSafe (bool peek = false)
2013-12-10 08:00:13 -05:00
{
if (!m_Queue.empty ())
{
2015-06-16 13:14:33 -04:00
auto el = m_Queue.front ();
2014-01-10 20:21:38 -05:00
if (!peek)
2024-10-12 17:51:26 -04:00
m_Queue.pop_front ();
2013-12-10 08:00:13 -05:00
return el;
2018-01-06 11:48:51 +08:00
}
2013-12-10 08:00:13 -05:00
return nullptr;
2018-01-06 11:48:51 +08:00
}
2013-12-10 08:00:13 -05:00
private:
2024-10-12 17:51:26 -04:00
std::list<Element> m_Queue;
2024-11-20 13:27:25 -05:00
mutable std::mutex m_QueueMutex;
2013-12-10 08:00:13 -05:00
std::condition_variable m_NonEmpty;
2018-01-06 11:48:51 +08:00
};
}
}
2013-12-10 08:00:13 -05:00
#endif