blob: 713370048415e44bf2d406b7ba17a038d1801dce [file] [log] [blame]
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_H
#define GRPC_CORE_LIB_IOMGR_EXECUTOR_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/gpr/spinlock.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/closure.h"
namespace grpc_core {
struct ThreadState {
gpr_mu mu;
size_t id; // For debugging purposes
const char* name; // Thread state name
gpr_cv cv;
grpc_closure_list elems;
size_t depth; // Number of closures in the closure list
bool shutdown;
bool queued_long_job;
grpc_core::Thread thd;
};
enum class ExecutorType {
DEFAULT = 0,
RESOLVER,
NUM_EXECUTORS // Add new values above this
};
enum class ExecutorJobType {
SHORT = 0,
LONG,
NUM_JOB_TYPES // Add new values above this
};
class Executor {
public:
Executor(const char* executor_name);
void Init();
/** Is the executor multi-threaded? */
bool IsThreaded() const;
/* Enable/disable threading - must be called after Init and Shutdown(). Never
* call SetThreading(false) in the middle of an application */
void SetThreading(bool threading);
/** Shutdown the executor, running all pending work as part of the call */
void Shutdown();
/** Enqueue the closure onto the executor. is_short is true if the closure is
* a short job (i.e expected to not block and complete quickly) */
void Enqueue(grpc_closure* closure, grpc_error* error, bool is_short);
// TODO(sreek): Currently we have two executors (available globally): The
// default executor and the resolver executor.
//
// Some of the functions below operate on the DEFAULT executor only while some
// operate of ALL the executors. This is a bit confusing and should be cleaned
// up in future (where we make all the following functions take ExecutorType
// and/or JobType)
// Initialize ALL the executors
static void InitAll();
static void Run(grpc_closure* closure, grpc_error* error,
ExecutorType executor_type = ExecutorType::DEFAULT,
ExecutorJobType job_type = ExecutorJobType::SHORT);
// Shutdown ALL the executors
static void ShutdownAll();
// Set the threading mode for ALL the executors
static void SetThreadingAll(bool enable);
// Set the threading mode for ALL the executors
static void SetThreadingDefault(bool enable);
// Return if a given executor is running in threaded mode (i.e if
// SetThreading(true) was called previously on that executor)
static bool IsThreaded(ExecutorType executor_type);
// Return if the DEFAULT executor is threaded
static bool IsThreadedDefault();
private:
static size_t RunClosures(const char* executor_name, grpc_closure_list list);
static void ThreadMain(void* arg);
const char* name_;
ThreadState* thd_state_;
size_t max_threads_;
gpr_atm num_threads_;
gpr_spinlock adding_thread_lock_;
};
// Global initializer for executor
void grpc_executor_global_init();
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */