Commit 332577dd authored by satorux@chromium.org's avatar satorux@chromium.org

dbus: Add comments about the right way to expose methods

Along the way, fix the order in the test service used in unit tests.

BUG=332120
TEST=dbus_unittests pass as before

Review URL: https://codereview.chromium.org/125673003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243770 0039d316-1c4b-4281-b951-d872f2087c98
parent ca49fa84
...@@ -421,6 +421,10 @@ class CHROME_DBUS_EXPORT Bus : public base::RefCountedThreadSafe<Bus> { ...@@ -421,6 +421,10 @@ class CHROME_DBUS_EXPORT Bus : public base::RefCountedThreadSafe<Bus> {
// Requests the ownership of the given service name. // Requests the ownership of the given service name.
// Returns true on success, or the the service name is already obtained. // Returns true on success, or the the service name is already obtained.
// //
// Note that it's important to expose methods before requesting a service
// name with this method. See also ExportedObject::ExportMethodAndBlock()
// for details.
//
// BLOCKING CALL. // BLOCKING CALL.
virtual bool RequestOwnershipAndBlock(const std::string& service_name, virtual bool RequestOwnershipAndBlock(const std::string& service_name,
ServiceOwnershipOptions options); ServiceOwnershipOptions options);
......
...@@ -66,6 +66,14 @@ class CHROME_DBUS_EXPORT ExportedObject ...@@ -66,6 +66,14 @@ class CHROME_DBUS_EXPORT ExportedObject
// |method_callback| can safely reference objects in the origin thread // |method_callback| can safely reference objects in the origin thread
// (i.e. UI thread in most cases). // (i.e. UI thread in most cases).
// //
// IMPORTANT NOTE: You should export all methods before requesting a
// service name by Bus::RequestOwnership/AndBlock(). If you do it in the
// wrong order (i.e. request a service name then export methods), there
// will be a short time period where your service is unable to respond to
// method calls because these methods aren't yet exposed. This race is a
// real problem as clients may start calling methods of your service as
// soon as you acquire a service name, by watching the name owner change.
//
// BLOCKING CALL. // BLOCKING CALL.
virtual bool ExportMethodAndBlock(const std::string& interface_name, virtual bool ExportMethodAndBlock(const std::string& interface_name,
const std::string& method_name, const std::string& method_name,
......
...@@ -38,7 +38,7 @@ TestService::TestService(const Options& options) ...@@ -38,7 +38,7 @@ TestService::TestService(const Options& options)
: base::Thread("TestService"), : base::Thread("TestService"),
request_ownership_options_(options.request_ownership_options), request_ownership_options_(options.request_ownership_options),
dbus_task_runner_(options.dbus_task_runner), dbus_task_runner_(options.dbus_task_runner),
on_all_methods_exported_(false, false), on_name_obtained_(false, false),
num_exported_methods_(0) { num_exported_methods_(0) {
} }
...@@ -54,8 +54,8 @@ bool TestService::StartService() { ...@@ -54,8 +54,8 @@ bool TestService::StartService() {
bool TestService::WaitUntilServiceIsStarted() { bool TestService::WaitUntilServiceIsStarted() {
const base::TimeDelta timeout(TestTimeouts::action_max_timeout()); const base::TimeDelta timeout(TestTimeouts::action_max_timeout());
// Wait until all methods are exported. // Wait until the ownership of the service name is obtained.
return on_all_methods_exported_.TimedWait(timeout); return on_name_obtained_.TimedWait(timeout);
} }
void TestService::ShutdownAndBlock() { void TestService::ShutdownAndBlock() {
...@@ -138,6 +138,8 @@ void TestService::OnOwnership(base::Callback<void(bool)> callback, ...@@ -138,6 +138,8 @@ void TestService::OnOwnership(base::Callback<void(bool)> callback,
has_ownership_ = success; has_ownership_ = success;
LOG_IF(ERROR, !success) << "Failed to own: " << service_name; LOG_IF(ERROR, !success) << "Failed to own: " << service_name;
callback.Run(success); callback.Run(success);
on_name_obtained_.Signal();
} }
void TestService::OnExported(const std::string& interface_name, void TestService::OnExported(const std::string& interface_name,
...@@ -152,8 +154,15 @@ void TestService::OnExported(const std::string& interface_name, ...@@ -152,8 +154,15 @@ void TestService::OnExported(const std::string& interface_name,
} }
++num_exported_methods_; ++num_exported_methods_;
if (num_exported_methods_ == kNumMethodsToExport) if (num_exported_methods_ == kNumMethodsToExport) {
on_all_methods_exported_.Signal(); // As documented in exported_object.h, the service name should be
// requested after all methods are exposed.
bus_->RequestOwnership("org.chromium.TestService",
request_ownership_options_,
base::Bind(&TestService::OnOwnership,
base::Unretained(this),
base::Bind(&EmptyCallback)));
}
} }
void TestService::Run(base::MessageLoop* message_loop) { void TestService::Run(base::MessageLoop* message_loop) {
...@@ -163,12 +172,6 @@ void TestService::Run(base::MessageLoop* message_loop) { ...@@ -163,12 +172,6 @@ void TestService::Run(base::MessageLoop* message_loop) {
bus_options.dbus_task_runner = dbus_task_runner_; bus_options.dbus_task_runner = dbus_task_runner_;
bus_ = new Bus(bus_options); bus_ = new Bus(bus_options);
bus_->RequestOwnership("org.chromium.TestService",
request_ownership_options_,
base::Bind(&TestService::OnOwnership,
base::Unretained(this),
base::Bind(&EmptyCallback)));
exported_object_ = bus_->GetExportedObject( exported_object_ = bus_->GetExportedObject(
ObjectPath("/org/chromium/TestObject")); ObjectPath("/org/chromium/TestObject"));
......
...@@ -170,7 +170,7 @@ class TestService : public base::Thread { ...@@ -170,7 +170,7 @@ class TestService : public base::Thread {
Bus::ServiceOwnershipOptions request_ownership_options_; Bus::ServiceOwnershipOptions request_ownership_options_;
scoped_refptr<base::SequencedTaskRunner> dbus_task_runner_; scoped_refptr<base::SequencedTaskRunner> dbus_task_runner_;
base::WaitableEvent on_all_methods_exported_; base::WaitableEvent on_name_obtained_;
// The number of methods actually exported. // The number of methods actually exported.
int num_exported_methods_; int num_exported_methods_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment