OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 // |
| 5 // Broker RPC Server implementation. |
| 6 |
| 7 #include "ceee/ie/broker/broker_rpc_server.h" |
| 8 |
| 9 #include "base/atomic_sequence_num.h" |
| 10 #include "base/logging.h" |
| 11 #include "base/win_util.h" |
| 12 #include "broker_rpc_lib.h" // NOLINT |
| 13 #include "ceee/common/com_utils.h" |
| 14 #include "ceee/ie/broker/broker_module_util.h" |
| 15 #include "ceee/ie/broker/broker_rpc_utils.h" |
| 16 #include "ceee/ie/broker/chrome_postman.h" |
| 17 |
| 18 BrokerRpcServer::BrokerRpcServer() |
| 19 : is_started_(false), |
| 20 current_thread_(::GetCurrentThreadId()) { |
| 21 } |
| 22 |
| 23 BrokerRpcServer::~BrokerRpcServer() { |
| 24 DCHECK(current_thread_ == ::GetCurrentThreadId()); |
| 25 Stop(); |
| 26 } |
| 27 |
| 28 bool BrokerRpcServer::Start() { |
| 29 DCHECK(current_thread_ == ::GetCurrentThreadId()); |
| 30 |
| 31 if (is_started()) |
| 32 return true; |
| 33 |
| 34 std::wstring end_point = GetRpcEndPointAddress(); |
| 35 std::wstring protocol = kRpcProtocol; |
| 36 DCHECK(!protocol.empty()); |
| 37 DCHECK(!end_point.empty()); |
| 38 if (protocol.empty() || end_point.empty()) |
| 39 return false; |
| 40 |
| 41 LOG(INFO) << "RPC server is starting. Endpoint: " << end_point; |
| 42 // Tell RPC runtime to use local interprocess communication for given |
| 43 // end point. |
| 44 RPC_STATUS status = ::RpcServerUseProtseqEp( |
| 45 reinterpret_cast<RPC_WSTR>(&protocol[0]), |
| 46 RPC_C_PROTSEQ_MAX_REQS_DEFAULT, |
| 47 reinterpret_cast<RPC_WSTR>(&end_point[0]), |
| 48 NULL); |
| 49 LOG_IF(ERROR, RPC_S_OK != status && RPC_S_DUPLICATE_ENDPOINT != status) << |
| 50 "Failed to set protocol for RPC end point. RPC_STATUS=0x" << |
| 51 com::LogWe(status); |
| 52 if (RPC_S_OK == status || RPC_S_DUPLICATE_ENDPOINT == status) { |
| 53 // Register RPC interface with the RPC runtime. |
| 54 status = ::RpcServerRegisterIfEx(BrokerRpcServer_CeeeBroker_v1_1_s_ifspec, |
| 55 NULL, NULL, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL); |
| 56 LOG_IF(ERROR, RPC_S_OK != status) << |
| 57 "Failed to register RPC interface. RPC_STATUS=0x" << com::LogWe(status); |
| 58 if (RPC_S_OK == status) { |
| 59 // Start listen for RPC calls. |
| 60 status = ::RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE); |
| 61 LOG_IF(ERROR, RPC_S_OK != status) << |
| 62 "Failed to start listening. RPC_STATUS=0x" << com::LogWe(status); |
| 63 if (RPC_S_OK == status) { |
| 64 LOG(INFO) << "RPC server is started. Endpoint: " << end_point; |
| 65 is_started_ = true; |
| 66 } |
| 67 } |
| 68 } |
| 69 if (!is_started()) |
| 70 Stop(); |
| 71 |
| 72 return is_started(); |
| 73 } |
| 74 |
| 75 bool BrokerRpcServer::Stop() { |
| 76 DCHECK(current_thread_ == ::GetCurrentThreadId()); |
| 77 is_started_ = false; |
| 78 // Stop server listening for RPC. |
| 79 RPC_STATUS status = ::RpcMgmtStopServerListening(NULL); |
| 80 LOG_IF(WARNING, RPC_S_OK != status) << |
| 81 "Failed to stop listening. RPC_STATUS=0x" << com::LogWe(status); |
| 82 // Wait while server stops listening threads. |
| 83 status = ::RpcMgmtWaitServerListen(); |
| 84 LOG_IF(WARNING, RPC_S_OK != status) << |
| 85 "Failed to wait server listen. RPC_STATUS=0x" << com::LogWe(status); |
| 86 // Unregister RPC interface. |
| 87 status = ::RpcServerUnregisterIf( |
| 88 BrokerRpcServer_CeeeBroker_v1_1_s_ifspec, NULL, FALSE); |
| 89 LOG_IF(WARNING, RPC_S_OK != status) << |
| 90 "Failed to unregister interface. RPC_STATUS=0x" << com::LogWe(status); |
| 91 return RPC_S_OK == status; |
| 92 } |
| 93 |
| 94 bool BrokerRpcServer::is_started() const { |
| 95 DCHECK(current_thread_ == ::GetCurrentThreadId()); |
| 96 return is_started_; |
| 97 } |
| 98 |
| 99 static base::AtomicSequenceNumber current_broker_rpc_context( |
| 100 base::LINKER_INITIALIZED); |
| 101 |
| 102 BrokerContextHandle BrokerRpcServer_Connect(handle_t binding_handle) { |
| 103 // TODO(vitalybuka@google.com): Add client identity check. |
| 104 ceee_module_util::LockModule(); |
| 105 return reinterpret_cast<void*>(current_broker_rpc_context.GetNext() + 1); |
| 106 } |
| 107 |
| 108 void BrokerRpcServer_Disconnect( |
| 109 handle_t binding_handle, |
| 110 BrokerContextHandle* context) { |
| 111 DCHECK(context != NULL); |
| 112 if (context) |
| 113 *context = NULL; |
| 114 ceee_module_util::UnlockModule(); |
| 115 } |
| 116 |
| 117 // Called when client process terminated without releasing context handle. |
| 118 void __RPC_USER BrokerContextHandle_rundown(BrokerContextHandle context) { |
| 119 DCHECK(context != NULL); |
| 120 ceee_module_util::UnlockModule(); |
| 121 } |
| 122 |
| 123 void BrokerRpcServer_FireEvent( |
| 124 handle_t binding_handle, |
| 125 BSTR event_name, |
| 126 BSTR event_args) { |
| 127 DCHECK(ChromePostman::GetInstance()); |
| 128 if (ChromePostman::GetInstance()) |
| 129 ChromePostman::GetInstance()->FireEvent(event_name, event_args); |
| 130 } |
OLD | NEW |