aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/iomgr/exec_ctx.h
diff options
context:
space:
mode:
authorGravatar Yash Tibrewal <yashkt@google.com>2017-12-06 09:05:05 -0800
committerGravatar GitHub <noreply@github.com>2017-12-06 09:05:05 -0800
commitad4d2dde0052efbbf49d64b0843c45f0381cfeb3 (patch)
tree6a657f8c6179d873b34505cdc24bce9462ca68eb /src/core/lib/iomgr/exec_ctx.h
parenta3df36cc2505a89c2f481eea4a66a87b3002844a (diff)
Revert "All instances of exec_ctx being passed around in src/core removed"
Diffstat (limited to 'src/core/lib/iomgr/exec_ctx.h')
-rw-r--r--src/core/lib/iomgr/exec_ctx.h182
1 files changed, 53 insertions, 129 deletions
diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h
index b0c1740155..b415d2c255 100644
--- a/src/core/lib/iomgr/exec_ctx.h
+++ b/src/core/lib/iomgr/exec_ctx.h
@@ -21,8 +21,6 @@
#include <grpc/support/atm.h>
#include <grpc/support/cpu.h>
-#include <grpc/support/log.h>
-#include <grpc/support/tls.h>
#include "src/core/lib/iomgr/closure.h"
@@ -43,13 +41,6 @@ typedef struct grpc_combiner grpc_combiner;
should be given to not delete said call/channel from this exec_ctx */
#define GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP 2
-extern grpc_closure_scheduler* grpc_schedule_on_exec_ctx;
-
-gpr_timespec grpc_millis_to_timespec(grpc_millis millis, gpr_clock_type clock);
-grpc_millis grpc_timespec_to_millis_round_down(gpr_timespec timespec);
-grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec timespec);
-
-namespace grpc_core {
/** Execution context.
* A bag of data that collects information along a callstack.
* Generally created at public API entry points, and passed down as
@@ -70,130 +61,63 @@ namespace grpc_core {
* - Instances are always passed as the first argument to a function that
* takes it, and always as a pointer (grpc_exec_ctx is never copied).
*/
-class ExecCtx {
- public:
- /** Default Constructor */
-
- ExecCtx() : flags_(GRPC_EXEC_CTX_FLAG_IS_FINISHED) { Set(this); }
-
- /** Parameterised Constructor */
- ExecCtx(uintptr_t fl) : flags_(fl) { Set(this); }
-
- /** Destructor */
- ~ExecCtx() {
- flags_ |= GRPC_EXEC_CTX_FLAG_IS_FINISHED;
- Flush();
- Set(last_exec_ctx_);
- }
-
- /** Disallow copy and assignment operators */
- ExecCtx(const ExecCtx&) = delete;
- ExecCtx& operator=(const ExecCtx&) = delete;
-
- /** Return starting_cpu */
- unsigned starting_cpu() const { return starting_cpu_; }
-
- struct CombinerData {
- /* currently active combiner: updated only via combiner.c */
- grpc_combiner* active_combiner;
- /* last active combiner in the active combiner list */
- grpc_combiner* last_combiner;
- };
-
- /** Only to be used by grpc-combiner code */
- CombinerData* combiner_data() { return &combiner_data_; }
-
- /** Return pointer to grpc_closure_list */
- grpc_closure_list* closure_list() { return &closure_list_; }
-
- /** Return flags */
- uintptr_t flags() { return flags_; }
-
- /** Checks if there is work to be done */
- bool HasWork() {
- return combiner_data_.active_combiner != NULL ||
- !grpc_closure_list_empty(closure_list_);
- }
-
- /** Flush any work that has been enqueued onto this grpc_exec_ctx.
- * Caller must guarantee that no interfering locks are held.
- * Returns true if work was performed, false otherwise. */
- bool Flush();
-
- /** Returns true if we'd like to leave this execution context as soon as
-possible: useful for deciding whether to do something more or not depending
-on outside context */
- bool IsReadyToFinish() {
- if ((flags_ & GRPC_EXEC_CTX_FLAG_IS_FINISHED) == 0) {
- if (CheckReadyToFinish()) {
- flags_ |= GRPC_EXEC_CTX_FLAG_IS_FINISHED;
- return true;
- }
- return false;
- } else {
- return true;
- }
- }
-
- /** Returns the stored current time relative to start if valid,
- * otherwise refreshes the stored time, sets it valid and returns the new
- * value */
- grpc_millis Now();
-
- /** Invalidates the stored time value. A new time value will be set on calling
- * Now() */
- void InvalidateNow() { now_is_valid_ = false; }
-
- /** To be used only by shutdown code in iomgr */
- void SetNowIomgrShutdown() {
- now_ = GRPC_MILLIS_INF_FUTURE;
- now_is_valid_ = true;
- }
-
- /** To be used only for testing.
- * Sets the now value
- */
- void TestOnlySetNow(grpc_millis new_val) {
- now_ = new_val;
- now_is_valid_ = true;
- }
-
- /** Finish any pending work for a grpc_exec_ctx. Must be called before
- * the instance is destroyed, or work may be lost. */
- void Finish();
-
- /** Global initialization for ExecCtx. Called by iomgr */
- static void GlobalInit(void);
-
- /** Global shutdown for ExecCtx. Called by iomgr */
- static void GlobalShutdown(void) { gpr_tls_destroy(&exec_ctx_); }
-
- /** Gets pointer to current exec_ctx */
- static ExecCtx* Get() {
- return reinterpret_cast<ExecCtx*>(gpr_tls_get(&exec_ctx_));
- }
-
- protected:
- /** Check if ready to finish */
- virtual bool CheckReadyToFinish() { return false; }
+struct grpc_exec_ctx {
+ grpc_closure_list closure_list;
+ /** currently active combiner: updated only via combiner.c */
+ grpc_combiner* active_combiner;
+ /** last active combiner in the active combiner list */
+ grpc_combiner* last_combiner;
+ uintptr_t flags;
+ unsigned starting_cpu;
+ void* check_ready_to_finish_arg;
+ bool (*check_ready_to_finish)(grpc_exec_ctx* exec_ctx, void* arg);
+
+ bool now_is_valid;
+ grpc_millis now;
+};
- private:
- /** Set exec_ctx_ to exec_ctx */
- void Set(ExecCtx* exec_ctx) {
- gpr_tls_set(&exec_ctx_, reinterpret_cast<intptr_t>(exec_ctx));
+/* initializer for grpc_exec_ctx:
+ prefer to use GRPC_EXEC_CTX_INIT whenever possible */
+#define GRPC_EXEC_CTX_INITIALIZER(flags, finish_check, finish_check_arg) \
+ { \
+ GRPC_CLOSURE_LIST_INIT, NULL, NULL, flags, gpr_cpu_current_cpu(), \
+ finish_check_arg, finish_check, false, 0 \
}
- grpc_closure_list closure_list_ = GRPC_CLOSURE_LIST_INIT;
- CombinerData combiner_data_ = {nullptr, nullptr};
- uintptr_t flags_;
- unsigned starting_cpu_ = gpr_cpu_current_cpu();
+/* initialize an execution context at the top level of an API call into grpc
+ (this is safe to use elsewhere, though possibly not as efficient) */
+#define GRPC_EXEC_CTX_INIT \
+ GRPC_EXEC_CTX_INITIALIZER(GRPC_EXEC_CTX_FLAG_IS_FINISHED, NULL, NULL)
- bool now_is_valid_ = false;
- grpc_millis now_ = 0;
+extern grpc_closure_scheduler* grpc_schedule_on_exec_ctx;
- GPR_TLS_CLASS_DECL(exec_ctx_);
- ExecCtx* last_exec_ctx_ = Get();
-};
-} // namespace grpc_core
+bool grpc_exec_ctx_has_work(grpc_exec_ctx* exec_ctx);
+
+/** Flush any work that has been enqueued onto this grpc_exec_ctx.
+ * Caller must guarantee that no interfering locks are held.
+ * Returns true if work was performed, false otherwise. */
+bool grpc_exec_ctx_flush(grpc_exec_ctx* exec_ctx);
+/** Finish any pending work for a grpc_exec_ctx. Must be called before
+ * the instance is destroyed, or work may be lost. */
+void grpc_exec_ctx_finish(grpc_exec_ctx* exec_ctx);
+/** Returns true if we'd like to leave this execution context as soon as
+ possible: useful for deciding whether to do something more or not depending
+ on outside context */
+bool grpc_exec_ctx_ready_to_finish(grpc_exec_ctx* exec_ctx);
+/** A finish check that is never ready to finish */
+bool grpc_never_ready_to_finish(grpc_exec_ctx* exec_ctx, void* arg_ignored);
+/** A finish check that is always ready to finish */
+bool grpc_always_ready_to_finish(grpc_exec_ctx* exec_ctx, void* arg_ignored);
+
+void grpc_exec_ctx_global_init(void);
+
+void grpc_exec_ctx_global_init(void);
+void grpc_exec_ctx_global_shutdown(void);
+
+grpc_millis grpc_exec_ctx_now(grpc_exec_ctx* exec_ctx);
+void grpc_exec_ctx_invalidate_now(grpc_exec_ctx* exec_ctx);
+gpr_timespec grpc_millis_to_timespec(grpc_millis millis, gpr_clock_type clock);
+grpc_millis grpc_timespec_to_millis_round_down(gpr_timespec timespec);
+grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec timespec);
#endif /* GRPC_CORE_LIB_IOMGR_EXEC_CTX_H */