Clarify the thread-safeness of ObjectProxy::CallMethod(). |
|||||||
Issue descriptionAccording 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?
,
Nov 9 2017
,
Nov 15 2017
Thank you for reply. So let's move forward with 1).
,
Nov 15 2017
(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.
,
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
,
Nov 21 2017
,
Jan 22 2018
,
Jan 23 2018
|
|||||||
►
Sign in to add a comment |
|||||||
Comment 1 by satorux@chromium.org
, Nov 7 2017