mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-28 21:07:59 +03:00
Add WorkQueue class
This commit is contained in:
parent
15453e3d90
commit
cc71e894e1
3 changed files with 211 additions and 1 deletions
119
components/sceneutil/workqueue.cpp
Normal file
119
components/sceneutil/workqueue.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
#include "workqueue.hpp"
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
|
||||
void WorkTicket::waitTillDone()
|
||||
{
|
||||
if (mDone > 0)
|
||||
return;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
||||
while (mDone == 0)
|
||||
{
|
||||
mCondition.wait(&mMutex);
|
||||
}
|
||||
}
|
||||
|
||||
void WorkTicket::signalDone()
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
||||
mDone.exchange(1);
|
||||
mCondition.broadcast();
|
||||
}
|
||||
|
||||
WorkItem::WorkItem()
|
||||
: mTicket(new WorkTicket)
|
||||
{
|
||||
}
|
||||
|
||||
WorkItem::~WorkItem()
|
||||
{
|
||||
}
|
||||
|
||||
void WorkItem::doWork()
|
||||
{
|
||||
mTicket->signalDone();
|
||||
}
|
||||
|
||||
osg::ref_ptr<WorkTicket> WorkItem::getTicket()
|
||||
{
|
||||
return mTicket;
|
||||
}
|
||||
|
||||
WorkQueue::WorkQueue(int workerThreads)
|
||||
: mIsReleased(false)
|
||||
{
|
||||
for (int i=0; i<workerThreads; ++i)
|
||||
{
|
||||
WorkThread* thread = new WorkThread(this);
|
||||
mThreads.push_back(thread);
|
||||
thread->startThread();
|
||||
}
|
||||
}
|
||||
|
||||
WorkQueue::~WorkQueue()
|
||||
{
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
||||
while (mQueue.size())
|
||||
{
|
||||
WorkItem* item = mQueue.front();
|
||||
delete item;
|
||||
mQueue.pop();
|
||||
}
|
||||
mIsReleased = true;
|
||||
mCondition.broadcast();
|
||||
}
|
||||
|
||||
for (unsigned int i=0; i<mThreads.size(); ++i)
|
||||
{
|
||||
mThreads[i]->join();
|
||||
delete mThreads[i];
|
||||
}
|
||||
}
|
||||
|
||||
WorkTicket* WorkQueue::addWorkItem(WorkItem *item)
|
||||
{
|
||||
WorkTicket* ticket = item->getTicket().get();
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
||||
mQueue.push(item);
|
||||
mCondition.signal();
|
||||
return ticket;
|
||||
}
|
||||
|
||||
WorkItem *WorkQueue::removeWorkItem()
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
||||
while (!mQueue.size() && !mIsReleased)
|
||||
{
|
||||
mCondition.wait(&mMutex);
|
||||
}
|
||||
if (mQueue.size())
|
||||
{
|
||||
WorkItem* item = mQueue.front();
|
||||
mQueue.pop();
|
||||
return item;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WorkThread::WorkThread(WorkQueue *workQueue)
|
||||
: mWorkQueue(workQueue)
|
||||
{
|
||||
}
|
||||
|
||||
void WorkThread::run()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
WorkItem* item = mWorkQueue->removeWorkItem();
|
||||
if (!item)
|
||||
return;
|
||||
item->doWork();
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue