Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit bc16d60

Browse files
authored
Make fml::ScopedCleanupClosure std::move-able and add unit tests. (#45772)
Fixes flutter/flutter#134568.
1 parent 035932d commit bc16d60

File tree

4 files changed

+83
-1
lines changed

4 files changed

+83
-1
lines changed

ci/licenses_golden/excluded_files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
../../../flutter/fml/ascii_trie_unittests.cc
8484
../../../flutter/fml/backtrace_unittests.cc
8585
../../../flutter/fml/base32_unittest.cc
86+
../../../flutter/fml/closure_unittests.cc
8687
../../../flutter/fml/command_line_unittest.cc
8788
../../../flutter/fml/container_unittests.cc
8889
../../../flutter/fml/endianness_unittests.cc

fml/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ if (enable_unittests) {
319319
"ascii_trie_unittests.cc",
320320
"backtrace_unittests.cc",
321321
"base32_unittest.cc",
322+
"closure_unittests.cc",
322323
"command_line_unittest.cc",
323324
"container_unittests.cc",
324325
"endianness_unittests.cc",

fml/closure.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,19 @@ using closure = std::function<void()>;
2929
/// automatically at the end of the scope. This covers the cases
3030
/// where there are early returns as well.
3131
///
32-
class ScopedCleanupClosure {
32+
class ScopedCleanupClosure final {
3333
public:
3434
ScopedCleanupClosure() = default;
3535

36+
ScopedCleanupClosure(ScopedCleanupClosure&& other) {
37+
closure_ = other.Release();
38+
}
39+
40+
ScopedCleanupClosure& operator=(ScopedCleanupClosure&& other) {
41+
closure_ = other.Release();
42+
return *this;
43+
}
44+
3645
explicit ScopedCleanupClosure(const fml::closure& closure)
3746
: closure_(closure) {}
3847

fml/closure_unittests.cc

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "fml/closure.h"
6+
#include "gtest/gtest.h"
7+
8+
TEST(ScopedCleanupClosureTest, DestructorDoesNothingWhenNoClosureSet) {
9+
fml::ScopedCleanupClosure cleanup;
10+
11+
// Nothing should happen.
12+
}
13+
14+
TEST(ScopedCleanupClosureTest, ReleaseDoesNothingWhenNoClosureSet) {
15+
fml::ScopedCleanupClosure cleanup;
16+
17+
// Nothing should happen.
18+
EXPECT_EQ(nullptr, cleanup.Release());
19+
}
20+
21+
TEST(ScopedCleanupClosureTest, ClosureInvokedOnDestructorWhenSetInConstructor) {
22+
auto invoked = false;
23+
24+
{
25+
fml::ScopedCleanupClosure cleanup([&invoked]() { invoked = true; });
26+
27+
EXPECT_FALSE(invoked);
28+
}
29+
30+
EXPECT_TRUE(invoked);
31+
}
32+
33+
TEST(ScopedCleanupClosureTest, ClosureInvokedOnDestructorWhenSet) {
34+
auto invoked = false;
35+
36+
{
37+
fml::ScopedCleanupClosure cleanup;
38+
cleanup.SetClosure([&invoked]() { invoked = true; });
39+
40+
EXPECT_FALSE(invoked);
41+
}
42+
43+
EXPECT_TRUE(invoked);
44+
}
45+
46+
TEST(ScopedCleanupClosureTest, ClosureNotInvokedWhenMoved) {
47+
auto invoked = 0;
48+
49+
{
50+
fml::ScopedCleanupClosure cleanup([&invoked]() { invoked++; });
51+
fml::ScopedCleanupClosure cleanup2(std::move(cleanup));
52+
53+
EXPECT_EQ(0, invoked);
54+
}
55+
56+
EXPECT_EQ(1, invoked);
57+
}
58+
59+
TEST(ScopedCleanupClosureTest, ClosureNotInvokedWhenMovedViaAssignment) {
60+
auto invoked = 0;
61+
62+
{
63+
fml::ScopedCleanupClosure cleanup([&invoked]() { invoked++; });
64+
fml::ScopedCleanupClosure cleanup2;
65+
cleanup2 = std::move(cleanup);
66+
67+
EXPECT_EQ(0, invoked);
68+
}
69+
70+
EXPECT_EQ(1, invoked);
71+
}

0 commit comments

Comments
 (0)