From ad4d2dde0052efbbf49d64b0843c45f0381cfeb3 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 6 Dec 2017 09:05:05 -0800 Subject: Revert "All instances of exec_ctx being passed around in src/core removed" --- src/core/lib/iomgr/exec_ctx.h | 182 ++++++++++++------------------------------ 1 file changed, 53 insertions(+), 129 deletions(-) (limited to 'src/core/lib/iomgr/exec_ctx.h') 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 #include -#include -#include #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(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(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 */ -- cgit v1.2.3