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

Side by Side Diff: dbus/object_proxy.cc

Issue 10492005: dbus: Fix a subtle butterfly-effect bug in handling incoming messages (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 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/end_to_end_async_unittest.cc ('k') | no next file » | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/bus.h" 5 #include "dbus/bus.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/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 bool method_call_successful = false; 270 bool method_call_successful = false;
271 if (!response_message) { 271 if (!response_message) {
272 // The response is not received. 272 // The response is not received.
273 error_callback.Run(NULL); 273 error_callback.Run(NULL);
274 } else if (dbus_message_get_type(response_message) == 274 } else if (dbus_message_get_type(response_message) ==
275 DBUS_MESSAGE_TYPE_ERROR) { 275 DBUS_MESSAGE_TYPE_ERROR) {
276 // This will take |response_message| and release (unref) it. 276 // This will take |response_message| and release (unref) it.
277 scoped_ptr<dbus::ErrorResponse> error_response( 277 scoped_ptr<dbus::ErrorResponse> error_response(
278 dbus::ErrorResponse::FromRawMessage(response_message)); 278 dbus::ErrorResponse::FromRawMessage(response_message));
279 error_callback.Run(error_response.get()); 279 error_callback.Run(error_response.get());
280 // Delete the message on the D-Bus thread. See below for why.
281 bus_->PostTaskToDBusThread(
282 FROM_HERE,
283 base::Bind(&base::DeletePointer<dbus::ErrorResponse>,
284 error_response.release()));
280 } else { 285 } else {
281 // This will take |response_message| and release (unref) it. 286 // This will take |response_message| and release (unref) it.
282 scoped_ptr<dbus::Response> response( 287 scoped_ptr<dbus::Response> response(
283 dbus::Response::FromRawMessage(response_message)); 288 dbus::Response::FromRawMessage(response_message));
284 // The response is successfully received. 289 // The response is successfully received.
285 response_callback.Run(response.get()); 290 response_callback.Run(response.get());
291 // The message should be deleted on the D-Bus thread for a complicated
292 // reason:
293 //
294 // libdbus keeps track of the number of bytes in the incoming message
295 // queue to ensure that the data size in the queue is manageable. The
296 // bookkeeping is partly done via dbus_message_unref(), and immediately
297 // asks the client code (Chrome) to stop monitoring the underlying
298 // socket, if the number of bytes exceeds a certian number, which is set
299 // to 63MB, per dbus-transport.cc:
300 //
301 // /* Try to default to something that won't totally hose the system,
302 // * but doesn't impose too much of a limitation.
303 // */
304 // transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63;
305 //
306 // The monitoring of the socket is done on the D-Bus thread (see Watch
307 // class in bus.cc), hence we should stop the monitoring from D-Bus
308 // thread, not from the current thread here, which is likely UI thread.
309 bus_->PostTaskToDBusThread(
310 FROM_HERE,
311 base::Bind(&base::DeletePointer<dbus::Response>,
312 response.release()));
313
286 method_call_successful = true; 314 method_call_successful = true;
287 // Record time spent for the method call. Don't include failures. 315 // Record time spent for the method call. Don't include failures.
288 UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime", 316 UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime",
289 base::TimeTicks::Now() - start_time); 317 base::TimeTicks::Now() - start_time);
290 } 318 }
291 // Record if the method call is successful, or not. 1 if successful. 319 // Record if the method call is successful, or not. 1 if successful.
292 UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess", 320 UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess",
293 method_call_successful, 321 method_call_successful,
294 kSuccessRatioHistogramMaxValue); 322 kSuccessRatioHistogramMaxValue);
295 } 323 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 459
432 return DBUS_HANDLER_RESULT_HANDLED; 460 return DBUS_HANDLER_RESULT_HANDLED;
433 } 461 }
434 462
435 void ObjectProxy::RunMethod(base::TimeTicks start_time, 463 void ObjectProxy::RunMethod(base::TimeTicks start_time,
436 SignalCallback signal_callback, 464 SignalCallback signal_callback,
437 Signal* signal) { 465 Signal* signal) {
438 bus_->AssertOnOriginThread(); 466 bus_->AssertOnOriginThread();
439 467
440 signal_callback.Run(signal); 468 signal_callback.Run(signal);
441 delete signal; 469 // Delete the message on the D-Bus thread. See comments in
470 // RunResponseCallback().
471 bus_->PostTaskToDBusThread(
472 FROM_HERE,
473 base::Bind(&base::DeletePointer<dbus::Signal>, signal));
474
442 // Record time spent for handling the signal. 475 // Record time spent for handling the signal.
443 UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime", 476 UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime",
444 base::TimeTicks::Now() - start_time); 477 base::TimeTicks::Now() - start_time);
445 } 478 }
446 479
447 DBusHandlerResult ObjectProxy::HandleMessageThunk( 480 DBusHandlerResult ObjectProxy::HandleMessageThunk(
448 DBusConnection* connection, 481 DBusConnection* connection,
449 DBusMessage* raw_message, 482 DBusMessage* raw_message,
450 void* user_data) { 483 void* user_data) {
451 ObjectProxy* self = reinterpret_cast<ObjectProxy*>(user_data); 484 ObjectProxy* self = reinterpret_cast<ObjectProxy*>(user_data);
(...skipping 23 matching lines...) Expand all
475 reader.PopString(&error_message); 508 reader.PopString(&error_message);
476 LogMethodCallFailure(interface_name, 509 LogMethodCallFailure(interface_name,
477 method_name, 510 method_name,
478 error_response->GetErrorName(), 511 error_response->GetErrorName(),
479 error_message); 512 error_message);
480 } 513 }
481 response_callback.Run(NULL); 514 response_callback.Run(NULL);
482 } 515 }
483 516
484 } // namespace dbus 517 } // namespace dbus
OLDNEW
« no previous file with comments | « dbus/end_to_end_async_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698