• 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 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