2018-01-29 14:19:00 +00:00
|
|
|
#ifndef LLARP_THREADPOOL_HPP
|
|
|
|
#define LLARP_THREADPOOL_HPP
|
|
|
|
|
|
|
|
#include <llarp/threadpool.h>
|
2018-07-25 00:35:11 +00:00
|
|
|
#include <llarp/threading.hpp>
|
2018-01-29 14:19:00 +00:00
|
|
|
|
2018-08-08 18:02:08 +00:00
|
|
|
#include <functional>
|
2018-07-27 00:21:57 +00:00
|
|
|
#include <queue>
|
2018-07-25 00:35:11 +00:00
|
|
|
|
2018-01-29 14:27:24 +00:00
|
|
|
#include <thread>
|
2018-01-29 14:19:00 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace thread
|
|
|
|
{
|
2018-08-12 17:22:29 +00:00
|
|
|
typedef util::Mutex mtx_t;
|
|
|
|
typedef util::Lock lock_t;
|
2018-05-22 15:54:19 +00:00
|
|
|
struct Pool
|
|
|
|
{
|
2018-08-08 17:43:46 +00:00
|
|
|
virtual void
|
|
|
|
Spawn(size_t sz, const char* name);
|
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
void
|
|
|
|
QueueJob(const llarp_thread_job& job);
|
2018-07-11 13:20:14 +00:00
|
|
|
|
2018-08-08 17:43:46 +00:00
|
|
|
virtual void
|
2018-05-22 15:54:19 +00:00
|
|
|
Join();
|
2018-07-11 13:20:14 +00:00
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
void
|
|
|
|
Stop();
|
|
|
|
std::vector< std::thread > threads;
|
2018-01-29 14:27:24 +00:00
|
|
|
|
2018-07-27 00:21:57 +00:00
|
|
|
struct Job_t
|
|
|
|
{
|
|
|
|
uint32_t id;
|
2018-08-30 18:48:43 +00:00
|
|
|
void* user;
|
|
|
|
llarp_thread_work_func work;
|
|
|
|
|
|
|
|
Job_t() = default;
|
|
|
|
|
|
|
|
Job_t(uint32_t jobid, const llarp_thread_job& j)
|
|
|
|
: id(jobid), user(j.user), work(j.work)
|
2018-07-27 00:21:57 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
operator<(const Job_t& j) const
|
|
|
|
{
|
|
|
|
return id < j.id;
|
|
|
|
}
|
2018-08-30 18:48:43 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
operator()() const
|
|
|
|
{
|
|
|
|
work(user);
|
|
|
|
}
|
2018-07-27 00:21:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
std::priority_queue< Job_t > jobs;
|
|
|
|
uint32_t ids = 0;
|
2018-05-22 15:54:19 +00:00
|
|
|
mtx_t queue_mutex;
|
2018-08-12 17:22:29 +00:00
|
|
|
util::Condition condition;
|
|
|
|
util::Condition done;
|
2018-05-22 15:54:19 +00:00
|
|
|
bool stop;
|
|
|
|
};
|
2018-01-29 14:19:00 +00:00
|
|
|
|
2018-08-08 17:43:46 +00:00
|
|
|
struct IsolatedPool : public Pool
|
|
|
|
{
|
2018-08-08 18:02:08 +00:00
|
|
|
IsolatedPool(int flags) : Pool(), m_flags(flags)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-08-13 08:48:19 +00:00
|
|
|
virtual void
|
|
|
|
Spawn(size_t workers, const char* name);
|
2018-08-08 17:43:46 +00:00
|
|
|
|
2018-08-08 17:47:13 +00:00
|
|
|
void
|
|
|
|
Join();
|
|
|
|
|
2018-08-26 12:51:22 +00:00
|
|
|
/// isolate current thread
|
|
|
|
/// return true for success
|
|
|
|
/// return false for failure
|
|
|
|
/// set errno on fail
|
|
|
|
/// override me in subclass
|
|
|
|
virtual bool
|
|
|
|
IsolateCurrentProcess()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-08-08 18:02:08 +00:00
|
|
|
// override me to do specific setups after isolation
|
|
|
|
// return true for success
|
|
|
|
virtual bool
|
|
|
|
Isolated()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-08-18 14:01:21 +00:00
|
|
|
/// called when isolation failed
|
|
|
|
virtual void
|
|
|
|
Fail()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-08-08 18:02:08 +00:00
|
|
|
std::thread* m_isolated = nullptr;
|
|
|
|
int m_flags;
|
2018-08-26 12:51:22 +00:00
|
|
|
int m_IsolatedWorkers = 0;
|
|
|
|
const char* IsolatedName = nullptr;
|
2018-08-17 19:49:58 +00:00
|
|
|
|
|
|
|
virtual void
|
|
|
|
MainLoop()
|
|
|
|
{
|
|
|
|
}
|
2018-08-08 17:43:46 +00:00
|
|
|
};
|
|
|
|
|
2018-08-26 12:51:22 +00:00
|
|
|
struct _NetIsolatedPool : public IsolatedPool
|
2018-08-08 18:02:08 +00:00
|
|
|
{
|
2018-08-26 12:51:22 +00:00
|
|
|
_NetIsolatedPool(std::function< bool(void*, bool) > setupNet,
|
|
|
|
std::function< void(void*) > runMain, void* user);
|
|
|
|
|
|
|
|
/// implement me per platform
|
|
|
|
virtual bool
|
|
|
|
IsolateNetwork() = 0;
|
|
|
|
|
|
|
|
bool
|
|
|
|
IsolateCurrentProcess()
|
|
|
|
{
|
|
|
|
return IsolateNetwork();
|
|
|
|
}
|
2018-08-08 18:02:08 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
Isolated()
|
|
|
|
{
|
2018-08-18 14:01:21 +00:00
|
|
|
return m_NetSetup(m_user, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Fail()
|
|
|
|
{
|
|
|
|
m_NetSetup(m_user, false);
|
2018-08-08 18:02:08 +00:00
|
|
|
}
|
|
|
|
|
2018-08-17 19:49:58 +00:00
|
|
|
void
|
|
|
|
MainLoop()
|
|
|
|
{
|
|
|
|
m_RunMain(m_user);
|
2018-08-08 18:02:08 +00:00
|
|
|
}
|
|
|
|
|
2018-08-18 14:01:21 +00:00
|
|
|
std::function< bool(void*, bool) > m_NetSetup;
|
2018-08-17 19:49:58 +00:00
|
|
|
std::function< void(void*) > m_RunMain;
|
2018-08-09 19:02:17 +00:00
|
|
|
void* m_user;
|
2018-08-08 18:02:08 +00:00
|
|
|
};
|
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
} // namespace thread
|
2018-02-01 13:21:00 +00:00
|
|
|
} // namespace llarp
|
2018-01-29 14:19:00 +00:00
|
|
|
|
|
|
|
#endif
|