New issue
Advanced search Search tips

Issue 778329 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Nov 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 3
Type: Bug



Sign in to add a comment

Clarify the thread-safeness of ObjectProxy::CallMethod().

Project Member Reported by hidehiko@chromium.org, Oct 25 2017

Issue description

According to the document,
https://cs.chromium.org/chromium/src/dbus/object_proxy.h?l=123

"As it's called in the origin thread, |callback| can safely reference objects in the origin thread."

However, we have edge cases.
The callback will be sent to DBusThread once, and post back to the original thread.
If "post back" fails for some reason (e.g. on shutdown UI thread is stopped before DBusThread), the callback will be destroyed on DBusThread, including the bound arguments, so not safe enough, unfortunately.
One of the root causes of crbug.com/746463 is this.

We have several options;
1) Destroy callback on the original thread always. In case of failure, leak it. This is the same approach for base::PostTaskAndReply().

2) Let callers (i.e., here callers mean not only chromeos/dbus *Client implementation but also their callers, too) have the responsibility to ensure thread-safeness. I.e., add restriction that all bound arguments must be destroyable on a thread other than the original one.

3) Introduce a layer to handle it around chromeos/dbus. E.g., add a wrapper for ObjectProxy, which lives on UI. Like;

Wrapper::CallMethod(..., callback) {
  int call_id = current_call_id_++;
  callback_map_[call_id] = std::move(callback);
  proxy_->CallMethod(..., base::BindOnce(&OnCallMethod, weak_ptr_factory_.GetWeakptr(), call_id));
}

Wrapper::OnCallMethod(int call_id, ...) {
  auto it = callback_map_.find(call_id);
  If (it == end()) ... error ...;
  auto callback = std::move(it->second);
  callback_map_.erase(it);
  std::move(callback).Run(...);
}

then, let chromeos/dbus clients use it always, so that their callers can safely bind args.

In any case, it's nice to update the ObjectProxy::CallMethod()'s document.
D-Bus experts, WDYT?

 
sorry for the belated reply. I think 1) makes sense.
Components: OS>Systems
Owner: hidehiko@chromium.org
Status: Started (was: Untriaged)
Thank you for reply. So let's move forward with 1).
Cc: benchan@chromium.org
(1) seems reasonable. If a caller wants to avoid leaking the callback context, it needs to ensure appropriate thread ordering or thread safeness. It would be good to document that in the relevant header file in chrome/dbus.
Project Member

Comment 5 by bugdroid1@chromium.org, Nov 21 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/7f05f78dd4bf63066dfd2c9c5a99b4c2fb20e268

commit 7f05f78dd4bf63066dfd2c9c5a99b4c2fb20e268
Author: Hidehiko Abe <hidehiko@chromium.org>
Date: Tue Nov 21 06:01:39 2017

Delete callback for CallMethod always on the origin thread.

The callback may have bound arguments, which could be thread unsafe.
So, the callback needs to be destroyed on the origin thread
always.
If PostTask from D-Bus thread to the origin thread fails,
let the callback leak intentionally.

BUG= 778329 
TEST=Build. Ran trybot.

Change-Id: Ib9c1d82e71f5f199a2cea087f8265326fc1f3da2
Reviewed-on: https://chromium-review.googlesource.com/772034
Reviewed-by: Ryo Hashimoto <hashimoto@chromium.org>
Commit-Queue: Hidehiko Abe <hidehiko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#518145}
[modify] https://crrev.com/7f05f78dd4bf63066dfd2c9c5a99b4c2fb20e268/dbus/object_proxy.cc
[modify] https://crrev.com/7f05f78dd4bf63066dfd2c9c5a99b4c2fb20e268/dbus/object_proxy.h
[modify] https://crrev.com/7f05f78dd4bf63066dfd2c9c5a99b4c2fb20e268/dbus/util.h

Status: Fixed (was: Started)

Comment 7 by dchan@chromium.org, Jan 22 2018

Status: Archived (was: Fixed)

Comment 8 by dchan@chromium.org, Jan 23 2018

Status: Fixed (was: Archived)

Sign in to add a comment