blob: 8829138c5fa71e3baa1ed5c36fe160e7361a3e4d [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"
typedef struct {
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;
} ThreadState;
typedef enum {
GRPC_EXECUTOR_SHORT = 0,
GRPC_EXECUTOR_LONG,
GRPC_NUM_EXECUTOR_JOB_TYPES // Add new values above this
} GrpcExecutorJobType;
class GrpcExecutor {
public:
GrpcExecutor(const char* executor_name);
void Init();
/** Is the executor multi-threaded? */
bool IsThreaded() const;
/* Enable/disable threading - must be called after Init and Shutdown() */
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);
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 executor functions ==
typedef enum {
GRPC_DEFAULT_EXECUTOR = 0,
GRPC_RESOLVER_EXECUTOR,
GRPC_NUM_EXECUTORS // Add new values above this
} GrpcExecutorType;
// 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 executor_type
// and/or job_type)
// Initialize ALL the executors
void grpc_executor_init();
// Shutdown ALL the executors
void grpc_executor_shutdown();
// Set the threading mode for ALL the executors
void grpc_executor_set_threading(bool enable);
// Get the DEFAULT executor scheduler for the given job_type
grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type);
// Get the executor scheduler for a given executor_type and a job_type
grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type,
GrpcExecutorJobType job_type);
// Return if a given executor is running in threaded mode (i.e if
// grpc_executor_set_threading(true) was called previously on that executor)
bool grpc_executor_is_threaded(GrpcExecutorType executor_type);
// Return if the DEFAULT executor is threaded
bool grpc_executor_is_threaded();
#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */