To efficiently enforce various global and local limits, Happy Eyeballs
jobs uses two stand-alone HappyOrderEnforcer services that create job
calls. Thus, they need manual adjustments to preserve job context.
If similar changes are required in many places, we may want to add a
CodeContext member to the AsyncJob itself so that callbacks can
magically restore their context without service modifications (assuming
the job was created in or somehow provided the right context before
those callbacks).
#include "squid.h"
#include "AccessLogEntry.h"
+#include "base/CodeContext.h"
#include "CachePeer.h"
#include "errorpage.h"
#include "FwdState.h"
Must(!job.spareWaiting.callback);
jobs_.emplace_back(&job);
job.spareWaiting.position = std::prev(jobs_.end());
+ job.spareWaiting.codeContext = CodeContext::Current();
}
void
while (!jobs_.empty()) {
if (const auto jobPtr = jobs_.front().valid()) {
auto &job = *jobPtr;
- if (readyNow(job))
- job.spareWaiting.callback = notify(jobPtr); // and fall through to the next job
- else
+ if (!readyNow(job))
break; // the next job cannot be ready earlier (FIFO)
+ CallBack(job.spareWaiting.codeContext, [&] {
+ job.spareWaiting.callback = notify(jobPtr); // and fall through to the next job
+ });
}
jobs_.pop_front();
}
/// nullifies but does not cancel the callback
void clear() { *this = HappySpareWait(); }
+ CodeContext::Pointer codeContext; ///< requestor's context
+
/// a pending noteGavePrimeItsChance() or noteSpareAllowance() call
AsyncCall::Pointer callback;