void AsioBlockableChain::unblock() { for (AsioBlockable* cur = m_firstParent, *next; cur; cur = next) { next = cur->getNextParent(); // the onUnblocked handler may free cur switch (cur->getKind()) { case Kind::AsyncFunctionWaitHandleNode: getAsyncFunctionWaitHandleNode(cur)->onUnblocked(); break; case Kind::AsyncGeneratorWaitHandle: getAsyncGeneratorWaitHandle(cur)->onUnblocked(); break; case Kind::AwaitAllWaitHandle: getAwaitAllWaitHandle(cur)->onUnblocked(); break; case Kind::ConditionWaitHandle: getConditionWaitHandle(cur)->onUnblocked(); break; case Kind::GenArrayWaitHandle: getGenArrayWaitHandle(cur)->onUnblocked(); break; case Kind::GenMapWaitHandle: getGenMapWaitHandle(cur)->onUnblocked(); break; case Kind::GenVectorWaitHandle: getGenVectorWaitHandle(cur)->onUnblocked(); break; } } }
// Currently only AAWH utilizes this to handle failures. void AsioBlockableChain::removeFromChain(AsioBlockable* ab) { AsioBlockable* prev = nullptr; for (AsioBlockable* cur = m_firstParent, *next; cur; cur = next) { next = cur->getNextParent(); if (ab == cur) { // Found the AAWH we need to remove assert(cur->getKind() == Kind::AwaitAllWaitHandleNode); if (prev == nullptr) { m_firstParent = next; } else { prev->updateNextParent(next); } return; } prev = cur; } // We should always be able to find the parent. assert(false); }