|
|
|
@ -5,6 +5,7 @@
|
|
|
|
|
#include <mutex>
|
|
|
|
|
#include <thread>
|
|
|
|
|
#include <condition_variable>
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
|
|
namespace i2p
|
|
|
|
|
{
|
|
|
|
@ -46,6 +47,12 @@ namespace util
|
|
|
|
|
return el;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Wait ()
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
|
|
|
|
m_NonEmpty.wait (l);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Wait (int sec, int usec)
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
|
|
|
@ -98,27 +105,40 @@ namespace util
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
MsgQueue (): m_Thread (std::bind (&MsgQueue<Msg>::Run, this)) , running(1) {};
|
|
|
|
|
typedef std::function<void()> OnEmpty;
|
|
|
|
|
|
|
|
|
|
MsgQueue (): m_IsRunning (true), m_Thread (std::bind (&MsgQueue<Msg>::Run, this)) {};
|
|
|
|
|
void Stop()
|
|
|
|
|
{
|
|
|
|
|
running = 0;
|
|
|
|
|
m_IsRunning = false;
|
|
|
|
|
Queue<Msg>::WakeUp ();
|
|
|
|
|
m_Thread.join();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SetOnEmpty (OnEmpty const & e) { m_OnEmpty = e; };
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
void Run ()
|
|
|
|
|
{
|
|
|
|
|
Msg * msg = nullptr;
|
|
|
|
|
while ((msg = Queue<Msg>::GetNext ()) != nullptr && running)
|
|
|
|
|
while (m_IsRunning)
|
|
|
|
|
{
|
|
|
|
|
msg->Process ();
|
|
|
|
|
delete msg;
|
|
|
|
|
while (Msg * msg = Queue<Msg>::Get ())
|
|
|
|
|
{
|
|
|
|
|
msg->Process ();
|
|
|
|
|
delete msg;
|
|
|
|
|
}
|
|
|
|
|
if (m_OnEmpty != nullptr)
|
|
|
|
|
m_OnEmpty ();
|
|
|
|
|
Queue<Msg>::Wait ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
bool m_IsRunning;
|
|
|
|
|
std::thread m_Thread;
|
|
|
|
|
volatile int running;
|
|
|
|
|
OnEmpty m_OnEmpty;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|