summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjyasskin@chromium.org <jyasskin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-29 20:10:36 +0000
committerjyasskin@chromium.org <jyasskin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-29 20:10:36 +0000
commit1f7d92afe7d288c92ec4dcb9a2473221284bcfeb (patch)
tree9dd967c20e4b606ec9a53e18ccbe2149870aa86b
parenta6aeb63075e88ea771b3e940dcb985383ba4d123 (diff)
downloadchromium_src-1f7d92afe7d288c92ec4dcb9a2473221284bcfeb.zip
chromium_src-1f7d92afe7d288c92ec4dcb9a2473221284bcfeb.tar.gz
chromium_src-1f7d92afe7d288c92ec4dcb9a2473221284bcfeb.tar.bz2
Make sure that when a SupportsUserData is destroyed, objects destroyed transitively see it as empty.
BUG=358707 Review URL: https://codereview.chromium.org/298023008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273568 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/BUILD.gn1
-rw-r--r--base/base.gyp1
-rw-r--r--base/supports_user_data.cc5
-rw-r--r--base/supports_user_data_unittest.cc39
4 files changed, 46 insertions, 0 deletions
diff --git a/base/BUILD.gn b/base/BUILD.gn
index b4faecf..7a19b7a 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1173,6 +1173,7 @@ test("base_unittests") {
"strings/sys_string_conversions_unittest.cc",
"strings/utf_offset_string_conversions_unittest.cc",
"strings/utf_string_conversions_unittest.cc",
+ "supports_user_data_unittest.cc",
"sync_socket_unittest.cc",
"synchronization/cancellation_flag_unittest.cc",
"synchronization/condition_variable_unittest.cc",
diff --git a/base/base.gyp b/base/base.gyp
index df8c21b..710c229 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -578,6 +578,7 @@
'strings/sys_string_conversions_unittest.cc',
'strings/utf_offset_string_conversions_unittest.cc',
'strings/utf_string_conversions_unittest.cc',
+ 'supports_user_data_unittest.cc',
'sync_socket_unittest.cc',
'synchronization/cancellation_flag_unittest.cc',
'synchronization/condition_variable_unittest.cc',
diff --git a/base/supports_user_data.cc b/base/supports_user_data.cc
index 2a0263e..9689014 100644
--- a/base/supports_user_data.cc
+++ b/base/supports_user_data.cc
@@ -35,6 +35,11 @@ void SupportsUserData::DetachUserDataThread() {
SupportsUserData::~SupportsUserData() {
DCHECK(thread_checker_.CalledOnValidThread() || user_data_.empty());
+ DataMap local_user_data;
+ user_data_.swap(local_user_data);
+ // Now this->user_data_ is empty, and any destructors called transitively from
+ // the destruction of |local_user_data| will see it that way instead of
+ // examining a being-destroyed object.
}
} // namespace base
diff --git a/base/supports_user_data_unittest.cc b/base/supports_user_data_unittest.cc
new file mode 100644
index 0000000..f6afc37
--- /dev/null
+++ b/base/supports_user_data_unittest.cc
@@ -0,0 +1,39 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/supports_user_data.h"
+
+#include <vector>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace {
+
+struct TestSupportsUserData : public SupportsUserData {};
+
+struct UsesItself : public SupportsUserData::Data {
+ UsesItself(SupportsUserData* supports_user_data, const void* key)
+ : supports_user_data_(supports_user_data),
+ key_(key) {
+ }
+
+ virtual ~UsesItself() {
+ EXPECT_EQ(NULL, supports_user_data_->GetUserData(key_));
+ }
+
+ SupportsUserData* supports_user_data_;
+ const void* key_;
+};
+
+TEST(SupportsUserDataTest, ClearWorksRecursively) {
+ TestSupportsUserData supports_user_data;
+ char key = 0;
+ supports_user_data.SetUserData(&key,
+ new UsesItself(&supports_user_data, &key));
+ // Destruction of supports_user_data runs the actual test.
+}
+
+} // namespace
+} // namespace base