| Index: ceee/ie/broker/broker_rpc_server.cc
|
| ===================================================================
|
| --- ceee/ie/broker/broker_rpc_server.cc (revision 67655)
|
| +++ ceee/ie/broker/broker_rpc_server.cc (working copy)
|
| @@ -7,8 +7,9 @@
|
| #include "ceee/ie/broker/broker_rpc_server.h"
|
|
|
| #include "base/atomic_sequence_num.h"
|
| +#include "base/logging.h"
|
| #include "base/metrics/histogram.h"
|
| -#include "base/logging.h"
|
| +#include "base/process_util.h"
|
| #include "base/win_util.h"
|
| #include "broker_rpc_lib.h" // NOLINT
|
| #include "ceee/common/com_utils.h"
|
| @@ -16,10 +17,37 @@
|
| #include "ceee/ie/broker/broker_rpc_utils.h"
|
| #include "ceee/ie/broker/chrome_postman.h"
|
|
|
| +
|
| +namespace {
|
| // This lock ensures that histograms created by the broker are thread safe.
|
| // The histograms created here can be initialized on multiple threads.
|
| Lock g_metrics_lock;
|
|
|
| +// Endpoint name unique to this process.
|
| +wchar_t g_server_endpoint[kMaxEndpointSize + 1] = {0};
|
| +
|
| +RPC_STATUS PrepareEndpoint(std::wstring endpoint) {
|
| + std::wstring protocol = kRpcProtocol;
|
| + DCHECK(!protocol.empty());
|
| + DCHECK(!endpoint.empty());
|
| + if (protocol.empty() || endpoint.empty())
|
| + return false;
|
| + LOG(INFO) << "RPC server is starting. Endpoint: " << endpoint;
|
| + // Tell RPC runtime to use local interprocess communication for given
|
| + // end point.
|
| + RPC_STATUS status = ::RpcServerUseProtseqEp(
|
| + reinterpret_cast<RPC_WSTR>(&protocol[0]),
|
| + RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
|
| + reinterpret_cast<RPC_WSTR>(&endpoint[0]),
|
| + NULL);
|
| + LOG_IF(ERROR, RPC_S_OK != status && RPC_S_DUPLICATE_ENDPOINT != status) <<
|
| + "Failed to set protocol for RPC end point. RPC_STATUS=0x" <<
|
| + com::LogWe(status);
|
| + return status;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| BrokerRpcServer::BrokerRpcServer()
|
| : is_started_(false),
|
| current_thread_(::GetCurrentThreadId()) {
|
| @@ -36,24 +64,38 @@
|
| if (is_started())
|
| return true;
|
|
|
| - std::wstring end_point = GetRpcEndPointAddress();
|
| - std::wstring protocol = kRpcProtocol;
|
| - DCHECK(!protocol.empty());
|
| - DCHECK(!end_point.empty());
|
| - if (protocol.empty() || end_point.empty())
|
| + std::wstring endpoint = GetRpcEndpointAddress();
|
| +
|
| + LOG(INFO) << "Calculating unique endpoint name.";
|
| + const int kMaxTries = 100;
|
| + RPC_STATUS status = RPC_E_FAULT;
|
| + for (int try_num = 0; try_num < kMaxTries &&
|
| + wcslen(g_server_endpoint) == 0; ++try_num) {
|
| + std::wostringstream string_builder;
|
| + string_builder << base::TimeTicks::Now().ToInternalValue() << L"+" <<
|
| + base::GetCurrentProcId() << L"+" << endpoint;
|
| + std::wstring unique_endpoint = string_builder.str();
|
| + unique_endpoint.resize(std::min<size_t>(unique_endpoint.size(),
|
| + kMaxEndpointSize));
|
| +
|
| + LOG(INFO) << "Unique endpoint:" << unique_endpoint;
|
| + status = PrepareEndpoint(unique_endpoint);
|
| +
|
| + if (status == RPC_S_OK) { // RPC_S_DUPLICATE_ENDPOINT is not accepted.
|
| + DCHECK(unique_endpoint.size() < arraysize(g_server_endpoint));
|
| + wcscpy(g_server_endpoint, unique_endpoint.c_str());
|
| + }
|
| + }
|
| +
|
| + if (wcslen(g_server_endpoint) == 0) {
|
| + DCHECK(status != RPC_S_OK);
|
| + LOG(ERROR) << "Calculating unique endpoint name failed.";
|
| return false;
|
| + }
|
|
|
| - LOG(INFO) << "RPC server is starting. Endpoint: " << end_point;
|
| - // Tell RPC runtime to use local interprocess communication for given
|
| - // end point.
|
| - RPC_STATUS status = ::RpcServerUseProtseqEp(
|
| - reinterpret_cast<RPC_WSTR>(&protocol[0]),
|
| - RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
|
| - reinterpret_cast<RPC_WSTR>(&end_point[0]),
|
| - NULL);
|
| - LOG_IF(ERROR, RPC_S_OK != status && RPC_S_DUPLICATE_ENDPOINT != status) <<
|
| - "Failed to set protocol for RPC end point. RPC_STATUS=0x" <<
|
| - com::LogWe(status);
|
| + // Now we can setup fixed endpoint.
|
| + status = PrepareEndpoint(endpoint);
|
| +
|
| if (RPC_S_OK == status || RPC_S_DUPLICATE_ENDPOINT == status) {
|
| // Register RPC interface with the RPC runtime.
|
| status = ::RpcServerRegisterIfEx(BrokerRpcServer_CeeeBroker_v1_1_s_ifspec,
|
| @@ -66,7 +108,8 @@
|
| LOG_IF(ERROR, RPC_S_OK != status) <<
|
| "Failed to start listening. RPC_STATUS=0x" << com::LogWe(status);
|
| if (RPC_S_OK == status) {
|
| - LOG(INFO) << "RPC server is started. Endpoint: " << end_point;
|
| + LOG(INFO) << "RPC server is started. Endpoints: " << endpoint << " " <<
|
| + g_server_endpoint;
|
| is_started_ = true;
|
| }
|
| }
|
| @@ -93,6 +136,9 @@
|
| BrokerRpcServer_CeeeBroker_v1_1_s_ifspec, NULL, FALSE);
|
| LOG_IF(WARNING, RPC_S_OK != status) <<
|
| "Failed to unregister interface. RPC_STATUS=0x" << com::LogWe(status);
|
| +
|
| + g_server_endpoint[0] = 0;
|
| +
|
| return RPC_S_OK == status;
|
| }
|
|
|
| @@ -104,6 +150,15 @@
|
| static base::AtomicSequenceNumber current_broker_rpc_context(
|
| base::LINKER_INITIALIZED);
|
|
|
| +int BrokerRpcServer_GetServerEndpoint(handle_t handle, int max_size,
|
| + wchar_t* endpoint) {
|
| + endpoint[0] = 0;
|
| + int endpoint_size = wcslen(g_server_endpoint);
|
| + if (endpoint_size < max_size)
|
| + wcscpy(endpoint, g_server_endpoint);
|
| + return endpoint_size;
|
| +}
|
| +
|
| BrokerContextHandle BrokerRpcServer_Connect(handle_t binding_handle) {
|
| // TODO(vitalybuka@google.com): Add client identity check.
|
| ceee_module_util::LockModule();
|
|
|