Improve deferral management logic, to fix order-sensitive bug

This commit is contained in:
Michael Scire 2019-01-21 22:28:04 -08:00
parent f9d38856f3
commit de4c2ddae1

View File

@ -182,23 +182,27 @@ class WaitableManager : public SessionManagerBase {
/* We finished processing, and maybe that means we can stop deferring an object. */ /* We finished processing, and maybe that means we can stop deferring an object. */
{ {
std::scoped_lock lk{this_ptr->deferred_lock}; std::scoped_lock lk{this_ptr->deferred_lock};
bool undeferred_any = true;
for (auto it = this_ptr->deferred_waitables.begin(); it != this_ptr->deferred_waitables.end();) { while (undeferred_any) {
auto w = *it; undeferred_any = false;
Result rc = w->HandleDeferred(); for (auto it = this_ptr->deferred_waitables.begin(); it != this_ptr->deferred_waitables.end();) {
if (rc == 0xF601 || !w->IsDeferred()) { auto w = *it;
/* Remove from the deferred list, set iterator. */ Result rc = w->HandleDeferred();
it = this_ptr->deferred_waitables.erase(it); if (rc == 0xF601 || !w->IsDeferred()) {
if (rc == 0xF601) { /* Remove from the deferred list, set iterator. */
/* Delete the closed waitable. */ it = this_ptr->deferred_waitables.erase(it);
delete w; if (rc == 0xF601) {
/* Delete the closed waitable. */
delete w;
} else {
/* Add to the waitables list. */
this_ptr->AddWaitable(w);
undeferred_any = true;
}
} else { } else {
/* Add to the waitables list. */ /* Move on to the next deferred waitable. */
this_ptr->AddWaitable(w); it++;
} }
} else {
/* Move on to the next deferred waitable. */
it++;
} }
} }
} }