Application-callback execution context. A bag of data that collects information along a callstack. It is created on the stack at core entry points, and stored internally as a thread-local variable.
There are three key differences between this structure and ExecCtx:
- ApplicationCallbackExecCtx builds a list of application-level callbacks, but ExecCtx builds a list of internal callbacks to invoke.
- ApplicationCallbackExecCtx invokes its callbacks only at destruction; there is no explicit Flush method.
- If more than one ApplicationCallbackExecCtx is created on the thread's stack, only the one closest to the base of the stack is actually active and this is the only one that enqueues application callbacks. (Unlike ExecCtx, it is not feasible to prevent multiple of these on the stack since the executing application callback may itself enter core. However, the new one created will just pass callbacks through to the base one and those will not be executed until the return to the destructor of the base one, preventing unlimited stack growth.)
This structure exists because application callbacks may themselves cause a core re-entry (e.g., through a public API call) and if that call in turn causes another application-callback, there could be arbitrarily growing stacks of core re-entries. Instead, any application callbacks instead should not be invoked until other core work is done and other application callbacks have completed. To accomplish this, any application callback should be enqueued using ApplicationCallbackExecCtx::Enqueue .
CONVENTIONS:
- Instances of this must ALWAYS be constructed on the stack, never heap allocated.
- Instances of this are generally constructed before ExecCtx when needed. The only exception is for ExecCtx's that are explicitly flushed and that survive beyond the scope of the function that can cause application callbacks to be invoked (e.g., in the timer thread).
Generally, core entry points that may trigger application-level callbacks will have the following declarations:
ApplicationCallbackExecCtx callback_exec_ctx; ExecCtx exec_ctx;
This ordering is important to make sure that the ApplicationCallbackExecCtx is destroyed after the ExecCtx (to prevent the re-entry problem described above, as well as making sure that ExecCtx core callbacks are invoked first)
Definition at line 283 of file exec_ctx.h.