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

Side by Side Diff: dbus/exported_object.cc

Issue 7824054: Add some histograms to the D-Bus library: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rate->ratio Created 9 years, 3 months 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
« no previous file with comments | « dbus/exported_object.h ('k') | dbus/object_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include "dbus/exported_object.h" 5 #include "dbus/exported_object.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h" 9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/metrics/histogram.h"
11 #include "base/threading/thread_restrictions.h" 12 #include "base/threading/thread_restrictions.h"
12 #include "base/time.h" 13 #include "base/time.h"
13 #include "dbus/bus.h" 14 #include "dbus/bus.h"
14 #include "dbus/message.h" 15 #include "dbus/message.h"
15 #include "dbus/scoped_dbus_error.h" 16 #include "dbus/scoped_dbus_error.h"
16 17
17 namespace dbus { 18 namespace dbus {
18 19
19 namespace { 20 namespace {
20 21
22 // Used for success ratio histograms. 1 for success, 0 for failure.
23 const int kSuccessRatioHistogramMaxValue = 2;
24
21 // Gets the absolute method name by concatenating the interface name and 25 // Gets the absolute method name by concatenating the interface name and
22 // the method name. Used for building keys for method_table_ in 26 // the method name. Used for building keys for method_table_ in
23 // ExportedObject. 27 // ExportedObject.
24 std::string GetAbsoluteMethodName( 28 std::string GetAbsoluteMethodName(
25 const std::string& interface_name, 29 const std::string& interface_name,
26 const std::string& method_name) { 30 const std::string& method_name) {
27 return interface_name + "." + method_name; 31 return interface_name + "." + method_name;
28 } 32 }
29 33
30 } // namespace 34 } // namespace
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 // For signals, the object path should be set to the path to the sender 97 // For signals, the object path should be set to the path to the sender
94 // object, which is this exported object here. 98 // object, which is this exported object here.
95 signal->SetPath(object_path_); 99 signal->SetPath(object_path_);
96 100
97 // Increment the reference count so we can safely reference the 101 // Increment the reference count so we can safely reference the
98 // underlying signal message until the signal sending is complete. This 102 // underlying signal message until the signal sending is complete. This
99 // will be unref'ed in SendSignalInternal(). 103 // will be unref'ed in SendSignalInternal().
100 DBusMessage* signal_message = signal->raw_message(); 104 DBusMessage* signal_message = signal->raw_message();
101 dbus_message_ref(signal_message); 105 dbus_message_ref(signal_message);
102 106
107 const base::TimeTicks start_time = base::TimeTicks::Now();
103 // Bind() won't compile if we pass signal_message. See the comment at 108 // Bind() won't compile if we pass signal_message. See the comment at
104 // ObjectProxy::CallMethod() for details. 109 // ObjectProxy::CallMethod() for details.
105 bus_->PostTaskToDBusThread(FROM_HERE, 110 bus_->PostTaskToDBusThread(FROM_HERE,
106 base::Bind(&ExportedObject::SendSignalInternal, 111 base::Bind(&ExportedObject::SendSignalInternal,
107 this, 112 this,
113 start_time,
108 static_cast<void*>(signal_message))); 114 static_cast<void*>(signal_message)));
109 } 115 }
110 116
111 void ExportedObject::Unregister() { 117 void ExportedObject::Unregister() {
112 bus_->AssertOnDBusThread(); 118 bus_->AssertOnDBusThread();
113 119
114 if (!object_is_registered_) 120 if (!object_is_registered_)
115 return; 121 return;
116 122
117 bus_->UnregisterObjectPath(object_path_); 123 bus_->UnregisterObjectPath(object_path_);
(...skipping 21 matching lines...) Expand all
139 145
140 void ExportedObject::OnExported(OnExportedCallback on_exported_callback, 146 void ExportedObject::OnExported(OnExportedCallback on_exported_callback,
141 const std::string& interface_name, 147 const std::string& interface_name,
142 const std::string& method_name, 148 const std::string& method_name,
143 bool success) { 149 bool success) {
144 bus_->AssertOnOriginThread(); 150 bus_->AssertOnOriginThread();
145 151
146 on_exported_callback.Run(interface_name, method_name, success); 152 on_exported_callback.Run(interface_name, method_name, success);
147 } 153 }
148 154
149 void ExportedObject::SendSignalInternal(void* in_signal_message) { 155 void ExportedObject::SendSignalInternal(base::TimeTicks start_time,
156 void* in_signal_message) {
150 DBusMessage* signal_message = 157 DBusMessage* signal_message =
151 static_cast<DBusMessage*>(in_signal_message); 158 static_cast<DBusMessage*>(in_signal_message);
152 uint32 serial = 0; 159 uint32 serial = 0;
153 bus_->Send(signal_message, &serial); 160 bus_->Send(signal_message, &serial);
154 dbus_message_unref(signal_message); 161 dbus_message_unref(signal_message);
162 // Record time spent to send the the signal. This is not accurate as the
163 // signal will actually be sent from the next run of the message loop,
164 // but we can at least tell the number of signals sent.
165 UMA_HISTOGRAM_TIMES("DBus.SignalSendTime",
166 base::TimeTicks::Now() - start_time);
155 } 167 }
156 168
157 bool ExportedObject::Register() { 169 bool ExportedObject::Register() {
158 bus_->AssertOnDBusThread(); 170 bus_->AssertOnDBusThread();
159 171
160 if (object_is_registered_) 172 if (object_is_registered_)
161 return true; 173 return true;
162 174
163 ScopedDBusError error; 175 ScopedDBusError error;
164 176
(...skipping 23 matching lines...) Expand all
188 // raw_message will be unrefed on exit of the function. Increment the 200 // raw_message will be unrefed on exit of the function. Increment the
189 // reference so we can use it in MethodCall. 201 // reference so we can use it in MethodCall.
190 dbus_message_ref(raw_message); 202 dbus_message_ref(raw_message);
191 scoped_ptr<MethodCall> method_call( 203 scoped_ptr<MethodCall> method_call(
192 MethodCall::FromRawMessage(raw_message)); 204 MethodCall::FromRawMessage(raw_message));
193 const std::string interface = method_call->GetInterface(); 205 const std::string interface = method_call->GetInterface();
194 const std::string member = method_call->GetMember(); 206 const std::string member = method_call->GetMember();
195 207
196 if (interface.empty()) { 208 if (interface.empty()) {
197 // We don't support method calls without interface. 209 // We don't support method calls without interface.
210 LOG(WARNING) << "Interface is missing: " << method_call->ToString();
198 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 211 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
199 } 212 }
200 213
201 // Check if we know about the method. 214 // Check if we know about the method.
202 const std::string absolute_method_name = GetAbsoluteMethodName( 215 const std::string absolute_method_name = GetAbsoluteMethodName(
203 interface, member); 216 interface, member);
204 MethodTable::const_iterator iter = method_table_.find(absolute_method_name); 217 MethodTable::const_iterator iter = method_table_.find(absolute_method_name);
205 if (iter == method_table_.end()) { 218 if (iter == method_table_.end()) {
206 // Don't know about the method. 219 // Don't know about the method.
220 LOG(WARNING) << "Unknown method: " << method_call->ToString();
207 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 221 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
208 } 222 }
209 223
224 const base::TimeTicks start_time = base::TimeTicks::Now();
210 Response* response = NULL; 225 Response* response = NULL;
211 if (bus_->HasDBusThread()) { 226 if (bus_->HasDBusThread()) {
212 response_from_method_ = NULL; 227 response_from_method_ = NULL;
213 // Post a task to run the method in the origin thread. 228 // Post a task to run the method in the origin thread.
214 bus_->PostTaskToOriginThread(FROM_HERE, 229 bus_->PostTaskToOriginThread(FROM_HERE,
215 base::Bind(&ExportedObject::RunMethod, 230 base::Bind(&ExportedObject::RunMethod,
216 this, 231 this,
217 iter->second, 232 iter->second,
218 method_call.get())); 233 method_call.get()));
219 // Wait until the method call is done. Blocking is not desirable but we 234 // Wait until the method call is done. Blocking is not desirable but we
(...skipping 10 matching lines...) Expand all
230 // infinitely in the origin thread. No way to stop it from here. 245 // infinitely in the origin thread. No way to stop it from here.
231 CHECK(signaled) << "Method " << absolute_method_name << " not called"; 246 CHECK(signaled) << "Method " << absolute_method_name << " not called";
232 } 247 }
233 response = response_from_method_; 248 response = response_from_method_;
234 } else { 249 } else {
235 // If the D-Bus thread is not used, just call the method directly. We 250 // If the D-Bus thread is not used, just call the method directly. We
236 // don't need the complicated logic to wait for the method call to be 251 // don't need the complicated logic to wait for the method call to be
237 // complete. 252 // complete.
238 response = iter->second.Run(method_call.get()); 253 response = iter->second.Run(method_call.get());
239 } 254 }
255 // Record if the method call is successful, or not. 1 if successful.
256 UMA_HISTOGRAM_ENUMERATION("DBus.ExportedMethodHandleSuccess",
257 response ? 1 : 0,
258 kSuccessRatioHistogramMaxValue);
240 259
241 if (!response) { 260 if (!response) {
242 // Something bad happened in the method call. 261 // Something bad happened in the method call.
243 scoped_ptr<dbus::ErrorResponse> error_response( 262 scoped_ptr<dbus::ErrorResponse> error_response(
244 ErrorResponse::FromMethodCall(method_call.get(), 263 ErrorResponse::FromMethodCall(method_call.get(),
245 DBUS_ERROR_FAILED, 264 DBUS_ERROR_FAILED,
246 "error occurred in " + member)); 265 "error occurred in " + member));
247 dbus_connection_send(connection, error_response->raw_message(), NULL); 266 dbus_connection_send(connection, error_response->raw_message(), NULL);
248 return DBUS_HANDLER_RESULT_HANDLED; 267 return DBUS_HANDLER_RESULT_HANDLED;
249 } 268 }
250 269
251 // The method call was successful. 270 // The method call was successful.
252 dbus_connection_send(connection, response->raw_message(), NULL); 271 dbus_connection_send(connection, response->raw_message(), NULL);
253 delete response; 272 delete response;
273 // Record time spent to handle the the method call. Don't include failures.
274 UMA_HISTOGRAM_TIMES("DBus.ExportedMethodHandleTime",
275 base::TimeTicks::Now() - start_time);
254 276
255 return DBUS_HANDLER_RESULT_HANDLED; 277 return DBUS_HANDLER_RESULT_HANDLED;
256 } 278 }
257 279
258 void ExportedObject::RunMethod(MethodCallCallback method_call_callback, 280 void ExportedObject::RunMethod(MethodCallCallback method_call_callback,
259 MethodCall* method_call) { 281 MethodCall* method_call) {
260 bus_->AssertOnOriginThread(); 282 bus_->AssertOnOriginThread();
261 283
262 response_from_method_ = method_call_callback.Run(method_call); 284 response_from_method_ = method_call_callback.Run(method_call);
263 on_method_is_called_.Signal(); 285 on_method_is_called_.Signal();
(...skipping 10 matching lines...) Expand all
274 return self->HandleMessage(connection, raw_message); 296 return self->HandleMessage(connection, raw_message);
275 } 297 }
276 298
277 void ExportedObject::OnUnregisteredThunk(DBusConnection *connection, 299 void ExportedObject::OnUnregisteredThunk(DBusConnection *connection,
278 void* user_data) { 300 void* user_data) {
279 ExportedObject* self = reinterpret_cast<ExportedObject*>(user_data); 301 ExportedObject* self = reinterpret_cast<ExportedObject*>(user_data);
280 return self->OnUnregistered(connection); 302 return self->OnUnregistered(connection);
281 } 303 }
282 304
283 } // namespace dbus 305 } // namespace dbus
OLDNEW
« no previous file with comments | « dbus/exported_object.h ('k') | dbus/object_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698