diff options
author | jyasskin@chromium.org <jyasskin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-29 20:10:36 +0000 |
---|---|---|
committer | jyasskin@chromium.org <jyasskin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-29 20:10:36 +0000 |
commit | 1f7d92afe7d288c92ec4dcb9a2473221284bcfeb (patch) | |
tree | 9dd967c20e4b606ec9a53e18ccbe2149870aa86b | |
parent | a6aeb63075e88ea771b3e940dcb985383ba4d123 (diff) | |
download | chromium_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.gn | 1 | ||||
-rw-r--r-- | base/base.gyp | 1 | ||||
-rw-r--r-- | base/supports_user_data.cc | 5 | ||||
-rw-r--r-- | base/supports_user_data_unittest.cc | 39 |
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 |