Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(914)

Side by Side Diff: ceee/ie/broker/broker_rpc_client.cc

Issue 5258006: Restart of ceee_broker on crash. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Broker RPC Client implementation. 5 // Broker RPC Client implementation.
6 6
7 #include "ceee/ie/broker/broker_rpc_client.h" 7 #include "ceee/ie/broker/broker_rpc_client.h"
8 8
9 #include <atlbase.h> 9 #include <atlbase.h>
10 #include "base/lock.h" 10 #include "base/lock.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/tuple.h"
12 #include "base/win/scoped_comptr.h" 13 #include "base/win/scoped_comptr.h"
13 #include "broker_lib.h" // NOLINT 14 #include "broker_lib.h" // NOLINT
14 #include "broker_rpc_lib.h" // NOLINT 15 #include "broker_rpc_lib.h" // NOLINT
15 #include "ceee/common/com_utils.h" 16 #include "ceee/common/com_utils.h"
16 #include "ceee/ie/broker/broker_rpc_utils.h" 17 #include "ceee/ie/broker/broker_rpc_utils.h"
17 18
18 BrokerRpcClient::BrokerRpcClient() : context_(0), binding_handle_(NULL) { 19
20 namespace {
21
22 void LogRpcException(const char* str, unsigned int exception_code) {
23 LOG(ERROR) << str << com::LogWe(exception_code);
19 } 24 }
20 25
21 BrokerRpcClient::~BrokerRpcClient() { 26 HRESULT BindRpc(std::wstring endpoint, RPC_BINDING_HANDLE* binding_handle) {
22 Disconnect(); 27 DCHECK(binding_handle);
28 std::wstring protocol = kRpcProtocol;
29 DCHECK(!protocol.empty());
30 DCHECK(!endpoint.empty());
31 if (protocol.empty() || endpoint.empty() || binding_handle == NULL)
32 return E_INVALIDARG;
33
34 RPC_BINDING_HANDLE tmp_binding_handle = NULL;
35
36 // TODO(vitalybuka@google.com): There's no guarantee (aside from name
37 // uniqueness) that it will connect to an endpoint created by the same user.
38 // Hint: The missing invocation is RpcBindingSetAuthInfoEx.
39 LOG(INFO) << "Connecting to RPC server. Endpoint: " << endpoint;
40 RPC_WSTR string_binding = NULL;
41 // Create binding string with given protocol and end point.
42 RPC_STATUS status = ::RpcStringBindingCompose(
43 NULL,
44 reinterpret_cast<RPC_WSTR>(&protocol[0]),
45 NULL,
46 reinterpret_cast<RPC_WSTR>(&endpoint[0]),
47 NULL,
48 &string_binding);
49 LOG_IF(ERROR, RPC_S_OK != status) <<
50 "Failed to compose binding string. RPC_STATUS=0x" << com::LogWe(status);
51
52 if (RPC_S_OK == status) {
53 // Create binding from just generated binding string. Binding handle should
54 // used for PRC calls.
55 status = ::RpcBindingFromStringBinding(string_binding, &tmp_binding_handle);
56 LOG_IF(ERROR, RPC_S_OK != status) <<
57 "Failed to bind. RPC_STATUS=0x" << com::LogWe(status);
58 ::RpcStringFree(&string_binding);
59 if (RPC_S_OK == status) {
60 LOG(INFO) << "RPC client is connected. Endpoint: " << endpoint;
61 *binding_handle = tmp_binding_handle;
62 return S_OK;
63 }
64 }
65 ::RpcBindingFree(binding_handle);
66 return RPC_E_FAULT;
23 } 67 }
24 68
25 int HandleRpcException(unsigned int rpc_exception_code) { 69 int HandleRpcException(unsigned int rpc_exception_code) {
26 switch (rpc_exception_code) { 70 switch (rpc_exception_code) {
27 case STATUS_ACCESS_VIOLATION: 71 case STATUS_ACCESS_VIOLATION:
28 case STATUS_DATATYPE_MISALIGNMENT: 72 case STATUS_DATATYPE_MISALIGNMENT:
29 case STATUS_PRIVILEGED_INSTRUCTION: 73 case STATUS_PRIVILEGED_INSTRUCTION:
30 case STATUS_BREAKPOINT: 74 case STATUS_BREAKPOINT:
31 case STATUS_STACK_OVERFLOW: 75 case STATUS_STACK_OVERFLOW:
32 case STATUS_IN_PAGE_ERROR: 76 case STATUS_IN_PAGE_ERROR:
33 case STATUS_GUARD_PAGE_VIOLATION: 77 case STATUS_GUARD_PAGE_VIOLATION:
34 return EXCEPTION_CONTINUE_SEARCH; 78 return EXCEPTION_CONTINUE_SEARCH;
35 default: 79 default:
36 break; 80 break;
37 } 81 }
38 return EXCEPTION_EXECUTE_HANDLER; 82 return EXCEPTION_EXECUTE_HANDLER;
39 } 83 }
40 84
41 static void LogRpcException(const char* str, unsigned int exception_code) { 85 HRESULT GetServerEndpoint(RPC_BINDING_HANDLE binding_handle,
42 LOG(ERROR) << str << com::LogWe(exception_code); 86 int max_size,
87 wchar_t* endpoint) {
88 RpcTryExcept {
89 int endpoint_size = BrokerRpcClient_GetServerEndpoint(binding_handle,
90 max_size, endpoint);
91 if (endpoint_size > max_size)
92 return E_INVALIDARG;
93 return S_OK;
94 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
95 LogRpcException("RPC error in LockContext", RpcExceptionCode());
96 return RPC_E_FAULT;
97 } RpcEndExcept
98 }
99
100 } // namespace
101
102 BrokerRpcClient::BrokerRpcClient(bool allow_restarts)
103 : context_(0),
104 binding_handle_(NULL),
105 allow_restarts_(allow_restarts) {
106 }
107
108 BrokerRpcClient::~BrokerRpcClient() {
109 Disconnect();
43 } 110 }
44 111
45 void BrokerRpcClient::LockContext() { 112 void BrokerRpcClient::LockContext() {
46 RpcTryExcept { 113 RpcTryExcept {
47 context_ = BrokerRpcClient_Connect(binding_handle_); 114 context_ = BrokerRpcClient_Connect(binding_handle_);
48 } RpcExcept(HandleRpcException(RpcExceptionCode())) { 115 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
49 LogRpcException("RPC error in LockContext", RpcExceptionCode()); 116 LogRpcException("RPC error in LockContext", RpcExceptionCode());
50 } RpcEndExcept 117 } RpcEndExcept
51 } 118 }
52 119
53 void BrokerRpcClient::ReleaseContext() { 120 void BrokerRpcClient::ReleaseContext() {
54 RpcTryExcept { 121 RpcTryExcept {
55 BrokerRpcClient_Disconnect(binding_handle_, &context_); 122 BrokerRpcClient_Disconnect(binding_handle_, &context_);
56 } RpcExcept(HandleRpcException(RpcExceptionCode())) { 123 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
57 LogRpcException("RPC error in ReleaseContext", RpcExceptionCode()); 124 LogRpcException("RPC error in ReleaseContext", RpcExceptionCode());
58 } RpcEndExcept 125 } RpcEndExcept
59 } 126 }
60 127
128 HRESULT BrokerRpcClient::StartServer(IUnknown** server) {
129 base::win::ScopedComPtr<IUnknown> broker;
130 // TODO(vitalybuka@google.com): Start broker without COM after the last
131 // COM interface is removed.
132 HRESULT hr = broker.CreateInstance(CLSID_CeeeBroker);
133 LOG_IF(ERROR, FAILED(hr)) << "Failed to create broker. " << com::LogHr(hr);
134 if (FAILED(hr))
135 return hr;
136 *server = broker.Detach();
137 return S_OK;
138 }
139
61 HRESULT BrokerRpcClient::Connect(bool start_server) { 140 HRESULT BrokerRpcClient::Connect(bool start_server) {
62 if (is_connected()) 141 if (is_connected())
63 return S_OK; 142 return S_OK;
64 143
65 // Keep alive until RPC is connected. 144 // Keep alive until RPC is connected.
66 base::win::ScopedComPtr<ICeeeBrokerRegistrar> broker; 145 base::win::ScopedComPtr<IUnknown> broker;
67 if (start_server) { 146 if (start_server) {
68 // TODO(vitalybuka@google.com): Start broker without COM after the last 147 HRESULT hr = StartServer(broker.Receive());
69 // COM interface is removed.
70 HRESULT hr = broker.CreateInstance(CLSID_CeeeBroker);
71 LOG_IF(ERROR, FAILED(hr)) << "Failed to create broker. " << com::LogHr(hr);
72 if (FAILED(hr)) 148 if (FAILED(hr))
73 return hr; 149 return hr;
74 } 150 }
75 151
76 std::wstring end_point = GetRpcEndPointAddress(); 152 RPC_BINDING_HANDLE tmp_binding = NULL;
77 std::wstring protocol = kRpcProtocol; 153 if (SUCCEEDED(BindRpc(GetRpcEndpointAddress(), &tmp_binding))) {
78 DCHECK(!protocol.empty()); 154 wchar_t server_endpoint[kMaxEndpointSize + 1];
79 DCHECK(!end_point.empty()); 155 if (SUCCEEDED(GetServerEndpoint(tmp_binding, arraysize(server_endpoint),
80 if (protocol.empty() || end_point.empty()) 156 server_endpoint)) &&
81 return RPC_E_FAULT; 157 SUCCEEDED(BindRpc(server_endpoint, &binding_handle_))) {
82
83 // TODO(vitalybuka@google.com): There's no guarantee (aside from name
84 // uniqueness) that it will connect to an endpoint created by the same user.
85 // Hint: The missing invocation is RpcBindingSetAuthInfoEx.
86 LOG(INFO) << "Connecting to RPC server. Endpoint: " << end_point;
87 RPC_WSTR string_binding = NULL;
88 // Create binding string with given protocol and end point.
89 RPC_STATUS status = ::RpcStringBindingCompose(
90 NULL,
91 reinterpret_cast<RPC_WSTR>(&protocol[0]),
92 NULL,
93 reinterpret_cast<RPC_WSTR>(&end_point[0]),
94 NULL,
95 &string_binding);
96 LOG_IF(ERROR, RPC_S_OK != status) <<
97 "Failed to compose binding string. RPC_STATUS=0x" << com::LogWe(status);
98
99 if (RPC_S_OK == status) {
100 // Create binding from just generated binding string. Binding handle should
101 // used for PRC calls.
102 status = ::RpcBindingFromStringBinding(string_binding, &binding_handle_);
103 LOG_IF(ERROR, RPC_S_OK != status) <<
104 "Failed to bind. RPC_STATUS=0x" << com::LogWe(status);
105 ::RpcStringFree(&string_binding);
106 if (RPC_S_OK == status) {
107 LOG(INFO) << "RPC client is connected. Endpoint: " << end_point;
108 LockContext(); 158 LockContext();
109 } 159 }
160 RPC_STATUS status = ::RpcBindingFree(&tmp_binding);
161 LOG_IF(WARNING, RPC_S_OK != status) <<
162 "Failed to unbind. RPC_STATUS=0x" << com::LogWe(status);
110 } 163 }
164
111 if (!is_connected()) { 165 if (!is_connected()) {
112 Disconnect(); 166 Disconnect();
113 return RPC_E_FAULT; 167 return RPC_E_FAULT;
114 } 168 }
115 return S_OK; 169 return S_OK;
116 } 170 }
117 171
118 void BrokerRpcClient::Disconnect() { 172 void BrokerRpcClient::Disconnect() {
119 if (context_ != NULL) 173 if (context_ != NULL)
120 ReleaseContext(); 174 ReleaseContext();
121 if (binding_handle_ != NULL) { 175 if (binding_handle_ != NULL) {
122 RPC_STATUS status = ::RpcBindingFree(&binding_handle_); 176 RPC_STATUS status = ::RpcBindingFree(&binding_handle_);
123 LOG_IF(WARNING, RPC_S_OK != status) << 177 LOG_IF(WARNING, RPC_S_OK != status) <<
124 "Failed to unbind. RPC_STATUS=0x" << com::LogWe(status); 178 "Failed to unbind. RPC_STATUS=0x" << com::LogWe(status);
125 } 179 }
126 } 180 }
127 181
182 template<class Function, class Params>
183 HRESULT BrokerRpcClient::RunRpc(bool allow_restart,
184 Function rpc_function,
185 Params params) {
Sigurður Ásgeirsson 2010/11/30 13:47:48 const Params& to reduce copying
Vitaly Buka (NO REVIEWS) 2010/12/01 01:20:12 I need something modifiable to change binding hand
186 DCHECK(rpc_function);
187 if (!is_connected())
188 return RPC_E_FAULT;
189 RpcTryExcept {
190 DispatchToFunction(rpc_function, params);
191 return S_OK;
192 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
193 LogRpcException("RPC error in FireEvent", RpcExceptionCode());
194
195 if (allow_restart &&
196 RPC_S_OK != ::RpcMgmtIsServerListening(binding_handle_)) {
197 Disconnect();
198 if (SUCCEEDED(Connect(true))) {
199 params.a = binding_handle_;
200 return RunRpc(false, rpc_function, params);
201 }
202 }
203 return RPC_E_FAULT;
204 } RpcEndExcept
205 }
206
128 HRESULT BrokerRpcClient::FireEvent(const char* event_name, 207 HRESULT BrokerRpcClient::FireEvent(const char* event_name,
129 const char* event_args) { 208 const char* event_args) {
130 RpcTryExcept { 209 return RunRpc(allow_restarts_, &BrokerRpcClient_FireEvent,
Sigurður Ásgeirsson 2010/11/30 13:47:48 nit: drop method name down to next line.
Vitaly Buka (NO REVIEWS) 2010/12/01 01:20:12 Done.
131 BrokerRpcClient_FireEvent(binding_handle_, event_name, event_args); 210 MakeTuple(binding_handle_, event_name, event_args));
132 return S_OK;
133 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
134 LogRpcException("RPC error in FireEvent", RpcExceptionCode());
135 return RPC_E_FAULT;
136 } RpcEndExcept
137 } 211 }
138 212
139 HRESULT BrokerRpcClient::SendUmaHistogramTimes(const char* name, int sample) { 213 HRESULT BrokerRpcClient::SendUmaHistogramTimes(const char* name, int sample) {
140 RpcTryExcept { 214 return RunRpc(allow_restarts_, &BrokerRpcClient_SendUmaHistogramTimes,
Sigurður Ásgeirsson 2010/11/30 13:47:48 ditto.
Vitaly Buka (NO REVIEWS) 2010/12/01 01:20:12 Done.
141 BrokerRpcClient_SendUmaHistogramTimes(binding_handle_, name, sample); 215 MakeTuple(binding_handle_, name, sample));
142 return S_OK;
143 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
144 LogRpcException("RPC error in SendUmaHistogramTimes", RpcExceptionCode());
145 return RPC_E_FAULT;
146 } RpcEndExcept
147 } 216 }
148 217
149 HRESULT BrokerRpcClient::SendUmaHistogramData(const char* name, 218 HRESULT BrokerRpcClient::SendUmaHistogramData(const char* name,
150 int sample, 219 int sample,
151 int min, 220 int min,
152 int max, 221 int max,
153 int bucket_count) { 222 int bucket_count) {
154 RpcTryExcept { 223 return RunRpc(allow_restarts_, &BrokerRpcClient_SendUmaHistogramData,
155 BrokerRpcClient_SendUmaHistogramData( 224 MakeTuple(binding_handle_, name, sample, min, max, bucket_count));
156 binding_handle_, name, sample, min, max, bucket_count);
157 return S_OK;
158 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
159 LogRpcException("RPC error in SendUmaHistogramData", RpcExceptionCode());
160 return RPC_E_FAULT;
161 } RpcEndExcept
162 } 225 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698