Commit 075ca921 authored by Matthieu Martin's avatar Matthieu Martin Committed by Facebook Github Bot

Ensure unset called before set

Summary: Some of the RequestData's instances share same thread-local, and rely on strict ordering of unset/set

Reviewed By: djwatson

Differential Revision: D9138483

fbshipit-source-id: fba59a7f5619d54ed21d71a40fb2cc6ce0e93797
parent cf00ac58
......@@ -166,37 +166,30 @@ std::shared_ptr<RequestContext> RequestContext::setContext(
if (newCtx && curCtx) {
auto newLock = newCtx->state_.rlock();
auto curLock = curCtx->state_.rlock();
auto niter = newLock->callbackData_.begin();
auto nend = newLock->callbackData_.end();
auto citer = curLock->callbackData_.begin();
auto cend = curLock->callbackData_.end();
while (true) {
if (niter == nend) {
if (citer == cend) {
break;
}
(*citer)->onUnset();
++citer;
} else if (citer == cend || *niter < *citer) {
(*niter)->onSet();
++niter;
} else if (*citer < *niter) {
(*citer)->onUnset();
++citer;
} else {
DCHECK(*niter == *citer);
++niter;
++citer;
auto& newData = newLock->callbackData_;
auto& curData = curLock->callbackData_;
for (auto* callback : curData) {
if (newData.find(callback) == newData.end()) {
callback->onUnset();
}
}
std::swap(curCtx, newCtx);
for (auto* callback : newData) {
if (curData.find(callback) == curData.end()) {
callback->onSet();
}
}
} else if (newCtx) {
newCtx->onSet();
std::swap(curCtx, newCtx);
// Note: actually newCtx
curCtx->onSet();
} else if (curCtx) {
curCtx->onUnset();
std::swap(curCtx, newCtx);
}
std::swap(curCtx, newCtx);
}
// Note: actually curCtx
return newCtx;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment