• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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