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

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) {
Sigurður Ásgeirsson 2010/12/01 14:23:54 const & for endpoint.
Vitaly Buka corp 2010/12/01 19:06:04 I need modifiable string to avoid const_cast On 20
22 Disconnect(); 27 DCHECK(binding_handle);
Sigurður Ásgeirsson 2010/12/01 14:23:54 we typically do a NULL check explicitly e.g. DCHE
Vitaly Buka corp 2010/12/01 19:06:04 Done.
28 std::wstring protocol = kRpcProtocol;
29 DCHECK(!protocol.empty());
MAD 2010/12/01 16:35:23 Why do we need to put this in an std::wstring? And
Vitaly Buka corp 2010/12/01 19:06:04 RpcStringBindingCompose need non cost. So I can av
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;
MAD 2010/12/01 16:35:23 We should start using VLOG(n)...
Vitaly Buka corp 2010/12/01 19:06:04 Done.
40 RPC_WSTR string_binding = NULL;
41 // Create binding string with given protocol and end point.
MAD 2010/12/01 16:35:23 Actually, protocol is not given it's hard coded...
Vitaly Buka corp 2010/12/01 19:06:04 Done.
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);
MAD 2010/12/01 16:35:23 Could also use LogRpcException in an else clause b
Vitaly Buka corp 2010/12/01 19:06:04 Done.
51
52 if (RPC_S_OK == status) {
53 // Create binding from just generated binding string. Binding handle should
MAD 2010/12/01 16:35:23 should used -> should be used
Vitaly Buka corp 2010/12/01 19:06:04 Done.
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);
MAD 2010/12/01 16:35:23 What if :RpcStringBindingCompose() failed? What ar
Vitaly Buka corp 2010/12/01 19:06:04 Done.
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 } // namespace
42 LOG(ERROR) << str << com::LogWe(exception_code); 86
87 BrokerRpcClient::BrokerRpcClient(bool allow_restarts)
88 : context_(0),
89 binding_handle_(NULL),
90 allow_restarts_(allow_restarts) {
91 }
92
93 BrokerRpcClient::~BrokerRpcClient() {
94 Disconnect();
43 } 95 }
44 96
45 void BrokerRpcClient::LockContext() { 97 void BrokerRpcClient::LockContext() {
46 RpcTryExcept { 98 RpcTryExcept {
47 context_ = BrokerRpcClient_Connect(binding_handle_); 99 context_ = BrokerRpcClient_Connect(binding_handle_);
48 } RpcExcept(HandleRpcException(RpcExceptionCode())) { 100 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
49 LogRpcException("RPC error in LockContext", RpcExceptionCode()); 101 LogRpcException("RPC error in LockContext", RpcExceptionCode());
50 } RpcEndExcept 102 } RpcEndExcept
51 } 103 }
52 104
53 void BrokerRpcClient::ReleaseContext() { 105 void BrokerRpcClient::ReleaseContext() {
54 RpcTryExcept { 106 RpcTryExcept {
55 BrokerRpcClient_Disconnect(binding_handle_, &context_); 107 BrokerRpcClient_Disconnect(binding_handle_, &context_);
56 } RpcExcept(HandleRpcException(RpcExceptionCode())) { 108 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
57 LogRpcException("RPC error in ReleaseContext", RpcExceptionCode()); 109 LogRpcException("RPC error in ReleaseContext", RpcExceptionCode());
58 } RpcEndExcept 110 } RpcEndExcept
59 } 111 }
60 112
113 HRESULT BrokerRpcClient::StartServer(IUnknown** server) {
114 base::win::ScopedComPtr<IUnknown> broker;
115 // TODO(vitalybuka@google.com): Start broker without COM after the last
116 // COM interface is removed.
117 HRESULT hr = broker.CreateInstance(CLSID_CeeeBroker);
118 LOG_IF(ERROR, FAILED(hr)) << "Failed to create broker. " << com::LogHr(hr);
119 if (FAILED(hr))
120 return hr;
121 *server = broker.Detach();
122 return S_OK;
123 }
124
61 HRESULT BrokerRpcClient::Connect(bool start_server) { 125 HRESULT BrokerRpcClient::Connect(bool start_server) {
62 if (is_connected()) 126 if (is_connected())
63 return S_OK; 127 return S_OK;
64 128
65 // Keep alive until RPC is connected. 129 // Keep alive until RPC is connected.
66 base::win::ScopedComPtr<ICeeeBrokerRegistrar> broker; 130 base::win::ScopedComPtr<IUnknown> broker;
67 if (start_server) { 131 if (start_server) {
68 // TODO(vitalybuka@google.com): Start broker without COM after the last 132 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)) 133 if (FAILED(hr))
73 return hr; 134 return hr;
74 } 135 }
75 136
76 std::wstring end_point = GetRpcEndPointAddress(); 137 if (SUCCEEDED(BindRpc(GetRpcEndpointAddress(), &binding_handle_)))
77 std::wstring protocol = kRpcProtocol; 138 LockContext();
78 DCHECK(!protocol.empty());
79 DCHECK(!end_point.empty());
80 if (protocol.empty() || end_point.empty())
81 return RPC_E_FAULT;
82 139
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();
109 }
110 }
111 if (!is_connected()) { 140 if (!is_connected()) {
112 Disconnect(); 141 Disconnect();
113 return RPC_E_FAULT; 142 return RPC_E_FAULT;
114 } 143 }
115 return S_OK; 144 return S_OK;
116 } 145 }
117 146
118 void BrokerRpcClient::Disconnect() { 147 void BrokerRpcClient::Disconnect() {
119 if (context_ != NULL) 148 if (context_ != NULL)
120 ReleaseContext(); 149 ReleaseContext();
121 if (binding_handle_ != NULL) { 150 if (binding_handle_ != NULL) {
122 RPC_STATUS status = ::RpcBindingFree(&binding_handle_); 151 RPC_STATUS status = ::RpcBindingFree(&binding_handle_);
123 LOG_IF(WARNING, RPC_S_OK != status) << 152 LOG_IF(WARNING, RPC_S_OK != status) <<
124 "Failed to unbind. RPC_STATUS=0x" << com::LogWe(status); 153 "Failed to unbind. RPC_STATUS=0x" << com::LogWe(status);
125 } 154 }
126 } 155 }
127 156
157 template<class Function, class Params>
158 HRESULT BrokerRpcClient::RunRpc(bool allow_restart,
159 Function rpc_function,
160 Params params) {
Sigurður Ásgeirsson 2010/12/01 14:23:54 I would still suggest a const & here. As is, you a
Vitaly Buka corp 2010/12/01 19:06:04 Done.
161 DCHECK(rpc_function);
162 if (!is_connected())
163 return RPC_E_FAULT;
164 RpcTryExcept {
165 DispatchToFunction(rpc_function, params);
166 return S_OK;
167 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
168 LogRpcException("RPC error in FireEvent", RpcExceptionCode());
MAD 2010/12/01 16:35:23 FireEvent -> Proper function name...
Vitaly Buka corp 2010/12/01 19:06:04 Done.
169
170 if (allow_restart &&
171 RPC_S_OK != ::RpcMgmtIsServerListening(binding_handle_)) {
172 Disconnect();
173 if (SUCCEEDED(Connect(true))) {
174 params.a = binding_handle_;
Sigurður Ásgeirsson 2010/12/01 14:23:54 this is hopefully the less common case, so here yo
MAD 2010/12/01 16:35:23 I wish there was a way to validate that params.a i
Vitaly Buka corp 2010/12/01 19:06:04 Done.
Vitaly Buka corp 2010/12/01 19:06:04 MakeRefTuple allows to remove this assignment. I
MAD 2010/12/01 19:59:40 Ho, cool... Much better :-)
175 return RunRpc(false, rpc_function, params);
MAD 2010/12/01 16:35:23 We should find a way to avoid infinite recursivene
Vitaly Buka corp 2010/12/01 19:06:04 It is impossible because first arg is 'false'. On
MAD 2010/12/01 19:59:40 D'ho! I didn't read correctly... Sorry about that.
176 }
177 }
178 return RPC_E_FAULT;
179 } RpcEndExcept
180 }
181
128 HRESULT BrokerRpcClient::FireEvent(const char* event_name, 182 HRESULT BrokerRpcClient::FireEvent(const char* event_name,
129 const char* event_args) { 183 const char* event_args) {
130 RpcTryExcept { 184 return RunRpc(allow_restarts_,
131 BrokerRpcClient_FireEvent(binding_handle_, event_name, event_args); 185 &BrokerRpcClient_FireEvent,
132 return S_OK; 186 MakeTuple(binding_handle_, context_, event_name, event_args));
133 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
134 LogRpcException("RPC error in FireEvent", RpcExceptionCode());
135 return RPC_E_FAULT;
136 } RpcEndExcept
137 } 187 }
138 188
139 HRESULT BrokerRpcClient::SendUmaHistogramTimes(const char* name, int sample) { 189 HRESULT BrokerRpcClient::SendUmaHistogramTimes(const char* name, int sample) {
140 RpcTryExcept { 190 return RunRpc(allow_restarts_,
141 BrokerRpcClient_SendUmaHistogramTimes(binding_handle_, name, sample); 191 &BrokerRpcClient_SendUmaHistogramTimes,
142 return S_OK; 192 MakeTuple(binding_handle_, name, sample));
143 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
144 LogRpcException("RPC error in SendUmaHistogramTimes", RpcExceptionCode());
145 return RPC_E_FAULT;
146 } RpcEndExcept
147 } 193 }
148 194
149 HRESULT BrokerRpcClient::SendUmaHistogramData(const char* name, 195 HRESULT BrokerRpcClient::SendUmaHistogramData(const char* name,
150 int sample, 196 int sample,
151 int min, 197 int min,
152 int max, 198 int max,
153 int bucket_count) { 199 int bucket_count) {
154 RpcTryExcept { 200 return RunRpc(allow_restarts_,
155 BrokerRpcClient_SendUmaHistogramData( 201 &BrokerRpcClient_SendUmaHistogramData,
156 binding_handle_, name, sample, min, max, bucket_count); 202 MakeTuple(binding_handle_, name, sample, min, max,
157 return S_OK; 203 bucket_count));
158 } RpcExcept(HandleRpcException(RpcExceptionCode())) {
159 LogRpcException("RPC error in SendUmaHistogramData", RpcExceptionCode());
160 return RPC_E_FAULT;
161 } RpcEndExcept
162 } 204 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698