Implement IoBoundWorkSlot

This commit is contained in:
Alexander A. Klimov 2019-02-15 12:25:25 +01:00
parent fd239ba3fe
commit d7b465ce74
2 changed files with 43 additions and 0 deletions

View File

@ -64,6 +64,29 @@ void CpuBoundWork::Done()
}
}
IoBoundWorkSlot::IoBoundWorkSlot(boost::asio::yield_context yc)
: yc(yc)
{
IoEngine::Get().m_CpuBoundSemaphore.fetch_add(1);
}
IoBoundWorkSlot::~IoBoundWorkSlot()
{
auto& ioEngine (IoEngine::Get());
for (;;) {
auto availableSlots (ioEngine.m_CpuBoundSemaphore.fetch_sub(1));
if (availableSlots < 1) {
ioEngine.m_CpuBoundSemaphore.fetch_add(1);
ioEngine.m_AlreadyExpiredTimer.async_wait(yc);
continue;
}
break;
}
}
LazyInit<std::unique_ptr<IoEngine>> IoEngine::m_Instance ([]() { return std::unique_ptr<IoEngine>(new IoEngine()); });
IoEngine& IoEngine::Get()

View File

@ -55,6 +55,25 @@ private:
bool m_Done;
};
/**
* Scope break for CPU-bound work done in an I/O thread
*
* @ingroup base
*/
class IoBoundWorkSlot
{
public:
IoBoundWorkSlot(boost::asio::yield_context yc);
IoBoundWorkSlot(const IoBoundWorkSlot&) = delete;
IoBoundWorkSlot(IoBoundWorkSlot&&) = delete;
IoBoundWorkSlot& operator=(const IoBoundWorkSlot&) = delete;
IoBoundWorkSlot& operator=(IoBoundWorkSlot&&) = delete;
~IoBoundWorkSlot();
private:
boost::asio::yield_context yc;
};
/**
* Async I/O engine
*
@ -63,6 +82,7 @@ private:
class IoEngine
{
friend CpuBoundWork;
friend IoBoundWorkSlot;
public:
IoEngine(const IoEngine&) = delete;