1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_H 20 #define GRPC_CORE_LIB_IOMGR_EXECUTOR_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include "src/core/lib/gpr/spinlock.h" 25 #include "src/core/lib/gprpp/thd.h" 26 #include "src/core/lib/iomgr/closure.h" 27 28 namespace grpc_core { 29 30 struct ThreadState { 31 gpr_mu mu; 32 size_t id; // For debugging purposes 33 const char* name; // Thread state name 34 gpr_cv cv; 35 grpc_closure_list elems; 36 size_t depth; // Number of closures in the closure list 37 bool shutdown; 38 bool queued_long_job; 39 grpc_core::Thread thd; 40 }; 41 42 enum class ExecutorType { 43 DEFAULT = 0, 44 RESOLVER, 45 46 NUM_EXECUTORS // Add new values above this 47 }; 48 49 enum class ExecutorJobType { 50 SHORT = 0, 51 LONG, 52 NUM_JOB_TYPES // Add new values above this 53 }; 54 55 class Executor { 56 public: 57 explicit Executor(const char* executor_name); 58 59 void Init(); 60 61 /** Is the executor multi-threaded? */ 62 bool IsThreaded() const; 63 64 /* Enable/disable threading - must be called after Init and Shutdown(). Never 65 * call SetThreading(false) in the middle of an application */ 66 void SetThreading(bool threading); 67 68 /** Shutdown the executor, running all pending work as part of the call */ 69 void Shutdown(); 70 71 /** Enqueue the closure onto the executor. is_short is true if the closure is 72 * a short job (i.e expected to not block and complete quickly) */ 73 void Enqueue(grpc_closure* closure, grpc_error* error, bool is_short); 74 75 // TODO(sreek): Currently we have two executors (available globally): The 76 // default executor and the resolver executor. 77 // 78 // Some of the functions below operate on the DEFAULT executor only while some 79 // operate of ALL the executors. This is a bit confusing and should be cleaned 80 // up in future (where we make all the following functions take ExecutorType 81 // and/or JobType) 82 83 // Initialize ALL the executors 84 static void InitAll(); 85 86 static void Run(grpc_closure* closure, grpc_error* error, 87 ExecutorType executor_type = ExecutorType::DEFAULT, 88 ExecutorJobType job_type = ExecutorJobType::SHORT); 89 90 // Shutdown ALL the executors 91 static void ShutdownAll(); 92 93 // Set the threading mode for ALL the executors 94 static void SetThreadingAll(bool enable); 95 96 // Set the threading mode for ALL the executors 97 static void SetThreadingDefault(bool enable); 98 99 // Return if a given executor is running in threaded mode (i.e if 100 // SetThreading(true) was called previously on that executor) 101 static bool IsThreaded(ExecutorType executor_type); 102 103 // Return if the DEFAULT executor is threaded 104 static bool IsThreadedDefault(); 105 106 private: 107 static size_t RunClosures(const char* executor_name, grpc_closure_list list); 108 static void ThreadMain(void* arg); 109 110 const char* name_; 111 ThreadState* thd_state_; 112 size_t max_threads_; 113 gpr_atm num_threads_; 114 gpr_spinlock adding_thread_lock_; 115 }; 116 117 // Global initializer for executor 118 void grpc_executor_global_init(); 119 120 } // namespace grpc_core 121 122 #endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */ 123