[*] Lock access to wpWorkers (e037fc21, a7dfd899 cleanup cont) and remove a redundant write lock to solve a deadlock

This commit is contained in:
Reece Wilson 2023-11-11 12:32:16 +00:00
parent a7dfd899f8
commit 151bb106fb
3 changed files with 15 additions and 16 deletions

View File

@ -20,12 +20,14 @@ namespace Aurora::Async
AuSPtr<ThreadState> GroupState::GetThreadByIndex(ThreadId_t uIndex)
{
// TODO: deinit mutex
if (AuArraySize(this->wpWorkers) > uIndex)
{
if (auto pState = AuTryLockMemoryType(this->wpWorkers[uIndex]))
AU_LOCK_GUARD(this->deinitMutex);
if (AuArraySize(this->wpWorkers) > uIndex)
{
return pState;
if (auto pState = AuTryLockMemoryType(this->wpWorkers[uIndex]))
{
return pState;
}
}
}
@ -41,9 +43,12 @@ namespace Aurora::Async
void GroupState::Decommit(ThreadId_t id)
{
if (AuArraySize(this->wpWorkers) > id)
{
this->wpWorkers[id] = {};
AU_LOCK_GUARD(this->deinitMutex);
if (AuArraySize(this->wpWorkers) > id)
{
this->wpWorkers[id] = {};
}
}
AU_LOCK_GUARD(this->workersMutex);

View File

@ -25,6 +25,7 @@ namespace Aurora::Async
// tracked workers
AuThreadPrimitives::Mutex workersMutex;
AuFutexMutex deinitMutex;
AuBST<ThreadId_t, AuSPtr<ThreadState>> workers;
AuWPtr<ThreadState> wpWorkers[32]; // linear non-locking lookup table
//

View File

@ -176,7 +176,6 @@ namespace Aurora::Async
size_t ThreadPool::GetThreadWorkersCount(ThreadGroup_t group)
{
AU_LOCK_GUARD(this->pRWReadView);
return GetGroup(group)->workers.size();
}
@ -706,8 +705,6 @@ namespace Aurora::Async
AuBST<ThreadGroup_t, AuList<ThreadId_t>> ThreadPool::GetThreads()
{
AU_LOCK_GUARD(this->pRWReadView);
AuBST<ThreadGroup_t, AuList<ThreadId_t>> ret;
for (auto pGroup : this->threadGroups_)
@ -719,6 +716,7 @@ namespace Aurora::Async
continue;
}
AU_LOCK_GUARD(pGroup->workersMutex);
AuTryReserve(workers, pGroup->workers.size());
for (const auto &thread : pGroup->workers)
@ -764,11 +762,10 @@ namespace Aurora::Async
void ThreadPool::Signal(WorkerId_t workerId)
{
AU_LOCK_GUARD(this->pRWReadView);
auto group = GetGroup(workerId.first);
if (workerId.second == Async::kThreadIdAny)
{
AU_LOCK_GUARD(group->workersMutex);
for (auto &jobWorker : group->workers)
{
jobWorker.second->running->Set();
@ -782,8 +779,6 @@ namespace Aurora::Async
AuSPtr<AuLoop::ILoopSource> ThreadPool::WorkerToLoopSource(WorkerId_t workerId)
{
AU_LOCK_GUARD(this->pRWReadView);
auto a = GetThreadHandle(workerId);
if (!a)
{
@ -1288,7 +1283,6 @@ namespace Aurora::Async
}
{
AU_LOCK_GUARD(this->rwlock_->AsWritable());
state->Decommit(id.second);
}
}
@ -1361,8 +1355,6 @@ namespace Aurora::Async
AuList<AuSPtr<ThreadState>> ThreadPool::GetThreadHandles(WorkerId_t id)
{
AU_LOCK_GUARD(this->pRWReadView);
auto group = GetGroup(id.first);
if (!group)
{
@ -1379,6 +1371,7 @@ namespace Aurora::Async
}
else
{
AU_LOCK_GUARD(group->workersMutex);
for (const auto &[key, value] : group->workers)
{
ret.push_back(value);