diff options
author | sv-denisov <[email protected]> | 2023-01-14 15:13:39 +0300 |
---|---|---|
committer | sv-denisov <[email protected]> | 2023-01-14 15:13:39 +0300 |
commit | 3657be5988251fc9074ba5b86b62bfa985ff4643 (patch) | |
tree | 2f9eca1c7158569dec9e2397c39b1a3731a7ee1c /util/generic/ptr_ut.cpp | |
parent | 380ce27d41b76ca1640e48b7271681b3719d6be0 (diff) |
TSharedPtr::As()&: leakage fix
По следам https://a.yandex-team.ru/review/2996409/details
Исправлены случаи при неудачных кастах:
1. контрольный блок дёргается даже при указании на nullptr (нехорошо для атомиков)
2. если исходный шаред поинтер разрушится раньше, чем полученный nullptr (например, при возврате из функции), то ресурс утечёт
Diffstat (limited to 'util/generic/ptr_ut.cpp')
-rw-r--r-- | util/generic/ptr_ut.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/util/generic/ptr_ut.cpp b/util/generic/ptr_ut.cpp index 6e028725b4e..5f0fd2d4703 100644 --- a/util/generic/ptr_ut.cpp +++ b/util/generic/ptr_ut.cpp @@ -850,6 +850,11 @@ public: using TVirtualProbe::TVirtualProbe; }; +class TDerivedProbeSibling: public TVirtualProbe { +public: + using TVirtualProbe::TVirtualProbe; +}; + void TPointerTest::TestSharedPtrDowncast() { { NTesting::TProbeState probeState = {}; @@ -889,4 +894,43 @@ void TPointerTest::TestSharedPtrDowncast() { UNIT_ASSERT_VALUES_EQUAL(probeState.Destructors, 1); } + { + NTesting::TProbeState probeState = {}; + + { + TSimpleSharedPtr<TVirtualProbe> base = MakeSimpleShared<TDerivedProbe>(&probeState); + UNIT_ASSERT_VALUES_EQUAL(probeState.Constructors, 1); + + { + auto derivedSibling = base.As<TDerivedProbeSibling>(); + UNIT_ASSERT_VALUES_EQUAL(probeState.Constructors, 1); + + UNIT_ASSERT_VALUES_EQUAL(derivedSibling.Get(), nullptr); + UNIT_ASSERT_VALUES_UNEQUAL(base.ReferenceCounter(), derivedSibling.ReferenceCounter()); + + UNIT_ASSERT_VALUES_EQUAL(base.RefCount(), 1l); + UNIT_ASSERT_VALUES_EQUAL(derivedSibling.RefCount(), 0l); + } + + UNIT_ASSERT_VALUES_EQUAL(probeState.Destructors, 0); + } + + UNIT_ASSERT_VALUES_EQUAL(probeState.Destructors, 1); + } + { + NTesting::TProbeState probeState = {}; + + { + TSimpleSharedPtr<TVirtualProbe> base = MakeSimpleShared<TDerivedProbe>(&probeState); + UNIT_ASSERT_VALUES_EQUAL(probeState.Constructors, 1); + + auto derived = std::move(base).As<TDerivedProbeSibling>(); + UNIT_ASSERT_VALUES_EQUAL(derived.Get(), nullptr); + UNIT_ASSERT_VALUES_EQUAL(probeState.Constructors, 1); + UNIT_ASSERT_VALUES_EQUAL(probeState.CopyConstructors, 0); + UNIT_ASSERT_VALUES_EQUAL(probeState.Destructors, 0); + } + + UNIT_ASSERT_VALUES_EQUAL(probeState.Destructors, 1); + } } |