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 typedef struct { 29 gpr_mu mu; 30 size_t id; // For debugging purposes 31 const char* name; // Thread state name 32 gpr_cv cv; 33 grpc_closure_list elems; 34 size_t depth; // Number of closures in the closure list 35 bool shutdown; 36 bool queued_long_job; 37 grpc_core::Thread thd; 38 } ThreadState; 39 40 typedef enum { 41 GRPC_EXECUTOR_SHORT = 0, 42 GRPC_EXECUTOR_LONG, 43 GRPC_NUM_EXECUTOR_JOB_TYPES // Add new values above this 44 } GrpcExecutorJobType; 45 46 class GrpcExecutor { 47 public: 48 GrpcExecutor(const char* executor_name); 49 50 void Init(); 51 52 /** Is the executor multi-threaded? */ 53 bool IsThreaded() const; 54 55 /* Enable/disable threading - must be called after Init and Shutdown() */ 56 void SetThreading(bool threading); 57 58 /** Shutdown the executor, running all pending work as part of the call */ 59 void Shutdown(); 60 61 /** Enqueue the closure onto the executor. is_short is true if the closure is 62 * a short job (i.e expected to not block and complete quickly) */ 63 void Enqueue(grpc_closure* closure, grpc_error* error, bool is_short); 64 65 private: 66 static size_t RunClosures(const char* executor_name, grpc_closure_list list); 67 static void ThreadMain(void* arg); 68 69 const char* name_; 70 ThreadState* thd_state_; 71 size_t max_threads_; 72 gpr_atm num_threads_; 73 gpr_spinlock adding_thread_lock_; 74 }; 75 76 // == Global executor functions == 77 78 typedef enum { 79 GRPC_DEFAULT_EXECUTOR = 0, 80 GRPC_RESOLVER_EXECUTOR, 81 82 GRPC_NUM_EXECUTORS // Add new values above this 83 } GrpcExecutorType; 84 85 // TODO(sreek): Currently we have two executors (available globally): The 86 // default executor and the resolver executor. 87 // 88 // Some of the functions below operate on the DEFAULT executor only while some 89 // operate of ALL the executors. This is a bit confusing and should be cleaned 90 // up in future (where we make all the following functions take executor_type 91 // and/or job_type) 92 93 // Initialize ALL the executors 94 void grpc_executor_init(); 95 96 // Shutdown ALL the executors 97 void grpc_executor_shutdown(); 98 99 // Set the threading mode for ALL the executors 100 void grpc_executor_set_threading(bool enable); 101 102 // Get the DEFAULT executor scheduler for the given job_type 103 grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type); 104 105 // Get the executor scheduler for a given executor_type and a job_type 106 grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type, 107 GrpcExecutorJobType job_type); 108 109 // Return if a given executor is running in threaded mode (i.e if 110 // grpc_executor_set_threading(true) was called previously on that executor) 111 bool grpc_executor_is_threaded(GrpcExecutorType executor_type); 112 113 // Return if the DEFAULT executor is threaded 114 bool grpc_executor_is_threaded(); 115 116 #endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */ 117