diff options
-rw-r--r-- | include/grpc++/server.h | 18 | ||||
-rw-r--r-- | src/cpp/server/server.cc | 25 |
2 files changed, 43 insertions, 0 deletions
diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 1a62df5698..7bb3cdf915 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -56,6 +56,7 @@ class AsyncGenericService; class RpcService; class RpcServiceMethod; class ServerAsyncStreamingInterface; +class ServerContext; class ThreadPoolInterface; /// Models a gRPC server. @@ -84,6 +85,23 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook { /// call \a Shutdown for this function to ever return. void Wait(); + /// Global Callbacks + /// + /// Can be set exactly once per application to install hooks whenever + /// a server event occurs + class GlobalCallbacks { + public: + virtual ~GlobalCallbacks() {} + /// Called before application callback for each synchronous server request + virtual void PreSynchronousRequest(ServerContext* context) = 0; + /// Called after application callback for each synchronous server request + virtual void PostSynchronousRequest(ServerContext* context) = 0; + }; + /// Set the global callback object. Can only be called once. Does not take + /// ownership of callbacks, and expects the pointed to object to be alive + /// until all server objects in the process have been destroyed. + static void SetGlobalCallbacks(GlobalCallbacks* callbacks); + private: friend class AsyncGenericService; friend class AsynchronousService; diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 695e811654..377c1ed167 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -51,6 +51,22 @@ namespace grpc { +class DefaultGlobalCallbacks GRPC_FINAL : public Server::GlobalCallbacks { + public: + void PreSynchronousRequest(ServerContext* context) GRPC_OVERRIDE {} + void PostSynchronousRequest(ServerContext* context) GRPC_OVERRIDE {} +}; + +static Server::GlobalCallbacks* g_callbacks = nullptr; +static gpr_once g_once_init_callbacks = GPR_ONCE_INIT; + +static void InitGlobalCallbacks() { + if (g_callbacks == nullptr) { + static DefaultGlobalCallbacks default_global_callbacks; + g_callbacks = &default_global_callbacks; + } +} + class Server::UnimplementedAsyncRequestContext { protected: UnimplementedAsyncRequestContext() : generic_stream_(&server_context_) {} @@ -220,8 +236,10 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag { void Run() { ctx_.BeginCompletionOp(&call_); + g_callbacks->PreSynchronousRequest(&ctx_); method_->handler()->RunHandler(MethodHandler::HandlerParameter( &call_, &ctx_, request_payload_, call_.max_message_size())); + g_callbacks->PostSynchronousRequest(&ctx_); request_payload_ = nullptr; void* ignored_tag; bool ignored_ok; @@ -283,6 +301,7 @@ Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, server_(CreateServer(max_message_size, compression_options)), thread_pool_(thread_pool), thread_pool_owned_(thread_pool_owned) { + gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks); grpc_server_register_completion_queue(server_, cq_.cq(), nullptr); } @@ -304,6 +323,12 @@ Server::~Server() { delete sync_methods_; } +void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { + GPR_ASSERT(g_callbacks == nullptr); + GPR_ASSERT(callbacks != nullptr); + g_callbacks = callbacks; +} + bool Server::RegisterService(const grpc::string* host, RpcService* service) { for (int i = 0; i < service->GetMethodCount(); ++i) { RpcServiceMethod* method = service->GetMethod(i); |