This commit is contained in:
parent
9b74a623af
commit
3225d8cbda
@ -14,7 +14,7 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
struct IThreadPoolInternal
|
struct IThreadPoolInternal
|
||||||
{
|
{
|
||||||
virtual bool WaitFor(WorkerId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 ms) = 0;
|
virtual bool WaitFor(WorkerPId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 ms) = 0;
|
||||||
virtual void Run(WorkerId_t target, AuSPtr<IAsyncRunnable> runnable) = 0;
|
virtual void Run(WorkerId_t target, AuSPtr<IAsyncRunnable> runnable) = 0;
|
||||||
virtual AuSPtr<ThreadState> GetThreadHandle(WorkerId_t id) = 0;
|
virtual AuSPtr<ThreadState> GetThreadHandle(WorkerId_t id) = 0;
|
||||||
virtual IThreadPool *ToThreadPool() = 0;
|
virtual IThreadPool *ToThreadPool() = 0;
|
||||||
|
@ -63,18 +63,15 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
bool ThreadPool::WaitFor(WorkerPId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 timeoutMs)
|
bool ThreadPool::WaitFor(WorkerPId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 timeoutMs)
|
||||||
{
|
{
|
||||||
auto curThread = GetThreadState();
|
if (auto pCurThread = GetThreadState())
|
||||||
|
|
||||||
if (!curThread)
|
|
||||||
{
|
{
|
||||||
return Threading::WaitFor(primitive.get(), timeoutMs);
|
bool bWorkerIdMatches = (unlocker.second == pCurThread->thread.id.second) ||
|
||||||
}
|
((unlocker.second == Async::kThreadIdAny) &&
|
||||||
|
(GetThreadWorkersCount(unlocker.first) == 1));
|
||||||
|
|
||||||
bool workerIdMatches = (unlocker.second == curThread->thread.id.second) || ((unlocker.second == Async::kThreadIdAny) && (GetThreadWorkersCount(unlocker.first) == 1));
|
if ((unlocker.first == pCurThread->thread.id.first) &&
|
||||||
|
(unlocker.pool.get() == this) &&
|
||||||
if ((unlocker.first == curThread->thread.id.first) &&
|
(bWorkerIdMatches))
|
||||||
(unlocker.pool.get() == this) && // work group matches
|
|
||||||
(workerIdMatches)) // well, crap
|
|
||||||
{
|
{
|
||||||
|
|
||||||
bool queryAsync = false;
|
bool queryAsync = false;
|
||||||
@ -90,12 +87,15 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
AuSPtr<ThreadState> pHandle;
|
AuSPtr<ThreadState> pHandle;
|
||||||
|
|
||||||
|
if (auto pPool = unlocker.pool)
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(AuStaticCast<ThreadPool>(unlocker.pool)->rwlock_->AsReadable());
|
auto pPoolEx = AuStaticCast<ThreadPool>(unlocker.pool);
|
||||||
|
AU_LOCK_GUARD(pPoolEx->rwlock_->AsReadable());
|
||||||
|
|
||||||
if ((pHandle = AuStaticCast<ThreadPool>(unlocker.pool)->GetThreadHandle(unlocker)))
|
if ((pHandle = AuStaticCast<ThreadPool>(unlocker.pool)->GetThreadHandle(unlocker)))
|
||||||
{
|
{
|
||||||
@ -600,10 +600,14 @@ namespace Aurora::Async
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sync to shutdown threads to prevent a race condition whereby the async subsystem shuts down before the threads
|
// Sync to shutdown threads to prevent a race condition whereby the async subsystem shuts down before the threads
|
||||||
|
auto pSelf = AuThreads::GetThread();
|
||||||
for (const auto &thread : threads)
|
for (const auto &thread : threads)
|
||||||
|
{
|
||||||
|
if (thread.get() != pSelf)
|
||||||
{
|
{
|
||||||
thread->Exit();
|
thread->Exit();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Is dead flag
|
// Is dead flag
|
||||||
this->shutdownEvent_->Set();
|
this->shutdownEvent_->Set();
|
||||||
|
@ -25,8 +25,8 @@ namespace Aurora::Async
|
|||||||
ThreadPool();
|
ThreadPool();
|
||||||
|
|
||||||
// IThreadPoolInternal
|
// IThreadPoolInternal
|
||||||
bool WaitFor(WorkerPId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 ms);
|
bool WaitFor(WorkerPId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 ms) override;
|
||||||
bool WaitFor(WorkerId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 ms) override;
|
bool WaitFor(WorkerId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 ms);
|
||||||
void Run(WorkerId_t target, AuSPtr<IAsyncRunnable> runnable) override;
|
void Run(WorkerId_t target, AuSPtr<IAsyncRunnable> runnable) override;
|
||||||
void Run(WorkerId_t target, AuSPtr<IAsyncRunnable> runnable, bool bIncrement);
|
void Run(WorkerId_t target, AuSPtr<IAsyncRunnable> runnable, bool bIncrement);
|
||||||
IThreadPool *ToThreadPool() override;
|
IThreadPool *ToThreadPool() override;
|
||||||
|
@ -455,13 +455,62 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
bool WorkItem::BlockUntilComplete()
|
bool WorkItem::BlockUntilComplete()
|
||||||
{
|
{
|
||||||
if (!this->finishedEvent_) return false;
|
|
||||||
if (!this->worker_)
|
if (!this->worker_)
|
||||||
{
|
{
|
||||||
this->finishedEvent_->Wait();
|
this->finishedEvent_->Wait();
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
return this->owner_->WaitFor(this->worker_.value(), AuUnsafeRaiiToShared(this->finishedEvent_.AsPointer()), 0);
|
|
||||||
|
struct WaitProxy : Threading::IWaitable
|
||||||
|
{
|
||||||
|
AuThreadPrimitives::IEvent *pEvent {};
|
||||||
|
WaitProxy(AuThreadPrimitives::IEvent *pEvent) :
|
||||||
|
pEvent(pEvent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
bool HasOSHandle(AuMach &mach) override
|
||||||
|
{
|
||||||
|
return this->pEvent->HasOSHandle(mach);
|
||||||
|
}
|
||||||
|
bool HasLockImplementation() override
|
||||||
|
{
|
||||||
|
return this->pEvent->HasLockImplementation();
|
||||||
|
}
|
||||||
|
void Lock() override
|
||||||
|
{
|
||||||
|
return this->pEvent->Lock();
|
||||||
|
}
|
||||||
|
bool LockMS(AuUInt64 qwRelTimeoutInMs) override
|
||||||
|
{
|
||||||
|
return this->pEvent->LockMS(qwRelTimeoutInMs);
|
||||||
|
}
|
||||||
|
bool LockNS(AuUInt64 qwRelTimeoutInNs) override
|
||||||
|
{
|
||||||
|
return this->pEvent->LockNS(qwRelTimeoutInNs);
|
||||||
|
}
|
||||||
|
bool LockAbsMS(AuUInt64 qwAbsTimeoutInMs) override
|
||||||
|
{
|
||||||
|
return this->pEvent->LockAbsMS(qwAbsTimeoutInMs);
|
||||||
|
}
|
||||||
|
bool LockAbsNS(AuUInt64 qwAbsTimeoutInNs) override
|
||||||
|
{
|
||||||
|
return this->pEvent->LockAbsNS(qwAbsTimeoutInNs);
|
||||||
|
}
|
||||||
|
bool TryLock() override
|
||||||
|
{
|
||||||
|
return this->pEvent->TryLock();
|
||||||
|
}
|
||||||
|
void Unlock() override
|
||||||
|
{
|
||||||
|
// PATCH: ensure release notifications set the event!
|
||||||
|
this->pEvent->Set();
|
||||||
|
}
|
||||||
|
} waitProxy(this->finishedEvent_.AsPointer());
|
||||||
|
|
||||||
|
return this->owner_->WaitFor(this->worker_.value(),
|
||||||
|
AuUnsafeRaiiToShared(&waitProxy),
|
||||||
|
0 /*forever*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WorkItem::HasFinished()
|
bool WorkItem::HasFinished()
|
||||||
|
Loading…
Reference in New Issue
Block a user