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

Unified Diff: dbus/exported_object.cc

Issue 8175009: Eliminate a timed wait from ExportedObject::HandleMessage(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « dbus/exported_object.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dbus/exported_object.cc
diff --git a/dbus/exported_object.cc b/dbus/exported_object.cc
index d20702407c4a3e282834a0149c2fedd73a381f01..e4a1641fa6e5ee67692bd383da896237e07a139c 100644
--- a/dbus/exported_object.cc
+++ b/dbus/exported_object.cc
@@ -39,10 +39,7 @@ ExportedObject::ExportedObject(Bus* bus,
: bus_(bus),
service_name_(service_name),
object_path_(object_path),
- object_is_registered_(false),
- response_from_method_(NULL),
- on_method_is_called_(false /* manual_reset */,
- false /* initially_signaled */) {
+ object_is_registered_(false) {
}
ExportedObject::~ExportedObject() {
@@ -218,67 +215,76 @@ DBusHandlerResult ExportedObject::HandleMessage(
}
const base::TimeTicks start_time = base::TimeTicks::Now();
- Response* response = NULL;
if (bus_->HasDBusThread()) {
- response_from_method_ = NULL;
// Post a task to run the method in the origin thread.
bus_->PostTaskToOriginThread(FROM_HERE,
base::Bind(&ExportedObject::RunMethod,
this,
iter->second,
- method_call.get()));
- // Wait until the method call is done. Blocking is not desirable but we
- // should return the response to the dbus-daemon in the function, so we
- // don't have a choice. We wait in the D-Bus thread, so it should be ok.
- {
- // We need a timeout here in case the method gets stuck.
- const int kTimeoutSecs = 10;
- const base::TimeDelta timeout(
- base::TimeDelta::FromSeconds(kTimeoutSecs));
-
- const bool signaled = on_method_is_called_.TimedWait(timeout);
- // Method not called is a fatal error. The method is likely stuck
- // infinitely in the origin thread. No way to stop it from here.
- CHECK(signaled) << "Method " << absolute_method_name << " not called";
- }
- response = response_from_method_;
+ method_call.release(),
+ start_time));
} else {
// If the D-Bus thread is not used, just call the method directly. We
// don't need the complicated logic to wait for the method call to be
// complete.
- response = iter->second.Run(method_call.get());
+ // |response| will be deleted in OnMethodCompleted().
+ Response* response = iter->second.Run(method_call.get());
+ OnMethodCompleted(method_call.release(), response, start_time);
}
+
+ // It's valid to say HANDLED here, and send a method response at a later
+ // time from OnMethodCompleted() asynchronously.
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+void ExportedObject::RunMethod(MethodCallCallback method_call_callback,
+ MethodCall* method_call,
+ base::TimeTicks start_time) {
+ bus_->AssertOnOriginThread();
+
+ Response* response = method_call_callback.Run(method_call);
+ bus_->PostTaskToDBusThread(FROM_HERE,
+ base::Bind(&ExportedObject::OnMethodCompleted,
+ this,
+ method_call,
+ response,
+ start_time));
+}
+
+void ExportedObject::OnMethodCompleted(MethodCall* method_call,
+ Response* response,
+ base::TimeTicks start_time) {
+ bus_->AssertOnDBusThread();
+ scoped_ptr<MethodCall> method_call_deleter(method_call);
+ scoped_ptr<Response> response_deleter(response);
+
// Record if the method call is successful, or not. 1 if successful.
UMA_HISTOGRAM_ENUMERATION("DBus.ExportedMethodHandleSuccess",
response ? 1 : 0,
kSuccessRatioHistogramMaxValue);
+ // Check if the bus is still connected. If the method takes long to
+ // complete, the bus may be shut down meanwhile.
+ if (!bus_->is_connected())
+ return;
+
if (!response) {
// Something bad happened in the method call.
scoped_ptr<dbus::ErrorResponse> error_response(
- ErrorResponse::FromMethodCall(method_call.get(),
- DBUS_ERROR_FAILED,
- "error occurred in " + member));
- dbus_connection_send(connection, error_response->raw_message(), NULL);
- return DBUS_HANDLER_RESULT_HANDLED;
+ ErrorResponse::FromMethodCall(
+ method_call,
+ DBUS_ERROR_FAILED,
+ "error occurred in " + method_call->GetMember()));
+ bus_->Send(error_response->raw_message(), NULL);
+ return;
}
// The method call was successful.
- dbus_connection_send(connection, response->raw_message(), NULL);
- delete response;
+ bus_->Send(response->raw_message(), NULL);
+
// Record time spent to handle the the method call. Don't include failures.
UMA_HISTOGRAM_TIMES("DBus.ExportedMethodHandleTime",
base::TimeTicks::Now() - start_time);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-void ExportedObject::RunMethod(MethodCallCallback method_call_callback,
- MethodCall* method_call) {
- bus_->AssertOnOriginThread();
-
- response_from_method_ = method_call_callback.Run(method_call);
- on_method_is_called_.Signal();
}
void ExportedObject::OnUnregistered(DBusConnection* connection) {
« no previous file with comments | « dbus/exported_object.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698