| Index: ceee/ie/broker/broker_rpc_client.cc
|
| ===================================================================
|
| --- ceee/ie/broker/broker_rpc_client.cc (revision 67905)
|
| +++ ceee/ie/broker/broker_rpc_client.cc (working copy)
|
| @@ -9,17 +9,60 @@
|
| #include <atlbase.h>
|
| #include "base/lock.h"
|
| #include "base/logging.h"
|
| +#include "base/tuple.h"
|
| #include "base/win/scoped_comptr.h"
|
| #include "broker_lib.h" // NOLINT
|
| #include "broker_rpc_lib.h" // NOLINT
|
| #include "ceee/common/com_utils.h"
|
| #include "ceee/ie/broker/broker_rpc_utils.h"
|
|
|
| -BrokerRpcClient::BrokerRpcClient() : context_(0), binding_handle_(NULL) {
|
| +
|
| +namespace {
|
| +
|
| +void LogRpcException(const char* str, unsigned int exception_code) {
|
| + LOG(ERROR) << str << com::LogWe(exception_code);
|
| }
|
|
|
| -BrokerRpcClient::~BrokerRpcClient() {
|
| - Disconnect();
|
| +HRESULT BindRpc(std::wstring endpoint, RPC_BINDING_HANDLE* binding_handle) {
|
| + DCHECK(binding_handle != NULL);
|
| + std::wstring protocol = kRpcProtocol;
|
| + DCHECK(!protocol.empty());
|
| + DCHECK(!endpoint.empty());
|
| + if (protocol.empty() || endpoint.empty() || binding_handle == NULL)
|
| + return E_INVALIDARG;
|
| +
|
| + RPC_BINDING_HANDLE tmp_binding_handle = NULL;
|
| +
|
| + // TODO(vitalybuka@google.com): There's no guarantee (aside from name
|
| + // uniqueness) that it will connect to an endpoint created by the same user.
|
| + // Hint: The missing invocation is RpcBindingSetAuthInfoEx.
|
| + VLOG(1) << "Connecting to RPC server. Endpoint: " << endpoint;
|
| + RPC_WSTR string_binding = NULL;
|
| + // Create binding string for given end point.
|
| + RPC_STATUS status = ::RpcStringBindingCompose(
|
| + NULL,
|
| + reinterpret_cast<RPC_WSTR>(&protocol[0]),
|
| + NULL,
|
| + reinterpret_cast<RPC_WSTR>(&endpoint[0]),
|
| + NULL,
|
| + &string_binding);
|
| +
|
| + if (RPC_S_OK == status) {
|
| + // Create binding from just generated binding string. Binding handle should
|
| + // be used for PRC calls.
|
| + status = ::RpcBindingFromStringBinding(string_binding, &tmp_binding_handle);
|
| + ::RpcStringFree(&string_binding);
|
| + if (RPC_S_OK == status) {
|
| + VLOG(1) << "RPC client is connected. Endpoint: " << endpoint;
|
| + *binding_handle = tmp_binding_handle;
|
| + return S_OK;
|
| + } else {
|
| + LogRpcException("Failed to bind. RPC_STATUS:", status);
|
| + }
|
| + } else {
|
| + LogRpcException("Failed to compose binding string. RPC_STATUS:", status);
|
| + }
|
| + return RPC_E_FAULT;
|
| }
|
|
|
| int HandleRpcException(unsigned int rpc_exception_code) {
|
| @@ -38,10 +81,18 @@
|
| return EXCEPTION_EXECUTE_HANDLER;
|
| }
|
|
|
| -static void LogRpcException(const char* str, unsigned int exception_code) {
|
| - LOG(ERROR) << str << com::LogWe(exception_code);
|
| +} // namespace
|
| +
|
| +BrokerRpcClient::BrokerRpcClient(bool allow_restarts)
|
| + : context_(0),
|
| + binding_handle_(NULL),
|
| + allow_restarts_(allow_restarts) {
|
| }
|
|
|
| +BrokerRpcClient::~BrokerRpcClient() {
|
| + Disconnect();
|
| +}
|
| +
|
| void BrokerRpcClient::LockContext() {
|
| RpcTryExcept {
|
| context_ = BrokerRpcClient_Connect(binding_handle_);
|
| @@ -58,56 +109,33 @@
|
| } RpcEndExcept
|
| }
|
|
|
| +HRESULT BrokerRpcClient::StartServer(IUnknown** server) {
|
| + base::win::ScopedComPtr<IUnknown> broker;
|
| + // TODO(vitalybuka@google.com): Start broker without COM after the last
|
| + // COM interface is removed.
|
| + HRESULT hr = broker.CreateInstance(CLSID_CeeeBroker);
|
| + LOG_IF(ERROR, FAILED(hr)) << "Failed to create broker. " << com::LogHr(hr);
|
| + if (FAILED(hr))
|
| + return hr;
|
| + *server = broker.Detach();
|
| + return S_OK;
|
| +}
|
| +
|
| HRESULT BrokerRpcClient::Connect(bool start_server) {
|
| if (is_connected())
|
| return S_OK;
|
|
|
| // Keep alive until RPC is connected.
|
| - base::win::ScopedComPtr<ICeeeBrokerRegistrar> broker;
|
| + base::win::ScopedComPtr<IUnknown> broker;
|
| if (start_server) {
|
| - // TODO(vitalybuka@google.com): Start broker without COM after the last
|
| - // COM interface is removed.
|
| - HRESULT hr = broker.CreateInstance(CLSID_CeeeBroker);
|
| - LOG_IF(ERROR, FAILED(hr)) << "Failed to create broker. " << com::LogHr(hr);
|
| + HRESULT hr = StartServer(broker.Receive());
|
| if (FAILED(hr))
|
| return hr;
|
| }
|
|
|
| - std::wstring end_point = GetRpcEndPointAddress();
|
| - std::wstring protocol = kRpcProtocol;
|
| - DCHECK(!protocol.empty());
|
| - DCHECK(!end_point.empty());
|
| - if (protocol.empty() || end_point.empty())
|
| - return RPC_E_FAULT;
|
| + if (SUCCEEDED(BindRpc(GetRpcEndpointAddress(), &binding_handle_)))
|
| + LockContext();
|
|
|
| - // TODO(vitalybuka@google.com): There's no guarantee (aside from name
|
| - // uniqueness) that it will connect to an endpoint created by the same user.
|
| - // Hint: The missing invocation is RpcBindingSetAuthInfoEx.
|
| - LOG(INFO) << "Connecting to RPC server. Endpoint: " << end_point;
|
| - RPC_WSTR string_binding = NULL;
|
| - // Create binding string with given protocol and end point.
|
| - RPC_STATUS status = ::RpcStringBindingCompose(
|
| - NULL,
|
| - reinterpret_cast<RPC_WSTR>(&protocol[0]),
|
| - NULL,
|
| - reinterpret_cast<RPC_WSTR>(&end_point[0]),
|
| - NULL,
|
| - &string_binding);
|
| - LOG_IF(ERROR, RPC_S_OK != status) <<
|
| - "Failed to compose binding string. RPC_STATUS=0x" << com::LogWe(status);
|
| -
|
| - if (RPC_S_OK == status) {
|
| - // Create binding from just generated binding string. Binding handle should
|
| - // used for PRC calls.
|
| - status = ::RpcBindingFromStringBinding(string_binding, &binding_handle_);
|
| - LOG_IF(ERROR, RPC_S_OK != status) <<
|
| - "Failed to bind. RPC_STATUS=0x" << com::LogWe(status);
|
| - ::RpcStringFree(&string_binding);
|
| - if (RPC_S_OK == status) {
|
| - LOG(INFO) << "RPC client is connected. Endpoint: " << end_point;
|
| - LockContext();
|
| - }
|
| - }
|
| if (!is_connected()) {
|
| Disconnect();
|
| return RPC_E_FAULT;
|
| @@ -125,26 +153,42 @@
|
| }
|
| }
|
|
|
| -HRESULT BrokerRpcClient::FireEvent(const char* event_name,
|
| - const char* event_args) {
|
| +template<class Function, class Params>
|
| +HRESULT BrokerRpcClient::RunRpc(bool allow_restart,
|
| + Function rpc_function,
|
| + const Params& params) {
|
| + DCHECK(rpc_function);
|
| + if (!is_connected())
|
| + return RPC_E_FAULT;
|
| RpcTryExcept {
|
| - BrokerRpcClient_FireEvent(binding_handle_, context_, event_name,
|
| - event_args);
|
| + DispatchToFunction(rpc_function, params);
|
| return S_OK;
|
| } RpcExcept(HandleRpcException(RpcExceptionCode())) {
|
| - LogRpcException("RPC error in FireEvent", RpcExceptionCode());
|
| + LogRpcException("RPC error in RunRpc", RpcExceptionCode());
|
| +
|
| + if (allow_restart &&
|
| + RPC_S_OK != ::RpcMgmtIsServerListening(binding_handle_)) {
|
| + Disconnect();
|
| + if (SUCCEEDED(Connect(true))) {
|
| + return RunRpc(false, rpc_function, params);
|
| + }
|
| + }
|
| return RPC_E_FAULT;
|
| } RpcEndExcept
|
| }
|
|
|
| +HRESULT BrokerRpcClient::FireEvent(const char* event_name,
|
| + const char* event_args) {
|
| + return RunRpc(allow_restarts_,
|
| + &BrokerRpcClient_FireEvent,
|
| + MakeRefTuple(binding_handle_, context_, event_name,
|
| + event_args));
|
| +}
|
| +
|
| HRESULT BrokerRpcClient::SendUmaHistogramTimes(const char* name, int sample) {
|
| - RpcTryExcept {
|
| - BrokerRpcClient_SendUmaHistogramTimes(binding_handle_, name, sample);
|
| - return S_OK;
|
| - } RpcExcept(HandleRpcException(RpcExceptionCode())) {
|
| - LogRpcException("RPC error in SendUmaHistogramTimes", RpcExceptionCode());
|
| - return RPC_E_FAULT;
|
| - } RpcEndExcept
|
| + return RunRpc(allow_restarts_,
|
| + &BrokerRpcClient_SendUmaHistogramTimes,
|
| + MakeRefTuple(binding_handle_, name, sample));
|
| }
|
|
|
| HRESULT BrokerRpcClient::SendUmaHistogramData(const char* name,
|
| @@ -152,12 +196,8 @@
|
| int min,
|
| int max,
|
| int bucket_count) {
|
| - RpcTryExcept {
|
| - BrokerRpcClient_SendUmaHistogramData(
|
| - binding_handle_, name, sample, min, max, bucket_count);
|
| - return S_OK;
|
| - } RpcExcept(HandleRpcException(RpcExceptionCode())) {
|
| - LogRpcException("RPC error in SendUmaHistogramData", RpcExceptionCode());
|
| - return RPC_E_FAULT;
|
| - } RpcEndExcept
|
| + return RunRpc(allow_restarts_,
|
| + &BrokerRpcClient_SendUmaHistogramData,
|
| + MakeRefTuple(binding_handle_, name, sample, min, max,
|
| + bucket_count));
|
| }
|
|
|