Skip to content

Commit 5dd1de1

Browse files
Write verity first, then do fs verification am: 8704c83 am: e7dee68
Original change: https://android-review.googlesource.com/c/platform/system/update_engine/+/1696829 Change-Id: I094ddc43779fcf30784ab3f25f2e773bc593f1bb
2 parents 3c9703d + e7dee68 commit 5dd1de1

5 files changed

+316
-149
lines changed

common/scoped_task_id.h

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//
2+
// Copyright (C) 2021 The Android Open Source Project
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
#ifndef UPDATE_ENGINE_SCOPED_TASK_ID_H_
18+
#define UPDATE_ENGINE_SCOPED_TASK_ID_H_
19+
20+
#include <type_traits>
21+
#include <utility>
22+
23+
#include <base/bind.h>
24+
#include <brillo/message_loops/message_loop.h>
25+
26+
namespace chromeos_update_engine {
27+
28+
// This class provides unique_ptr like semantic for |MessageLoop::TaskId|, when
29+
// instance of this class goes out of scope, underlying task will be cancelled.
30+
class ScopedTaskId {
31+
using MessageLoop = brillo::MessageLoop;
32+
33+
public:
34+
constexpr ScopedTaskId() = default;
35+
36+
constexpr ScopedTaskId(ScopedTaskId&& other) noexcept {
37+
*this = std::move(other);
38+
}
39+
40+
constexpr ScopedTaskId& operator=(ScopedTaskId&& other) noexcept {
41+
std::swap(task_id_, other.task_id_);
42+
return *this;
43+
}
44+
45+
// Post a callback on current message loop, return true if succeeded, false if
46+
// the previous callback hasn't run yet, or scheduling failed at MessageLoop
47+
// side.
48+
[[nodiscard]] bool PostTask(const base::Location& from_here,
49+
base::OnceClosure&& callback,
50+
base::TimeDelta delay = {}) noexcept {
51+
return PostTask<decltype(callback)>(from_here, std::move(callback), delay);
52+
}
53+
[[nodiscard]] bool PostTask(const base::Location& from_here,
54+
std::function<void()>&& callback,
55+
base::TimeDelta delay = {}) noexcept {
56+
return PostTask<decltype(callback)>(from_here, std::move(callback), delay);
57+
}
58+
59+
~ScopedTaskId() noexcept { Cancel(); }
60+
61+
// Cancel the underlying managed task, true if cancel successful. False if no
62+
// task scheduled or task cancellation failed
63+
bool Cancel() noexcept {
64+
if (task_id_ != MessageLoop::kTaskIdNull) {
65+
if (MessageLoop::current()->CancelTask(task_id_)) {
66+
LOG(INFO) << "Cancelled task id " << task_id_;
67+
task_id_ = MessageLoop::kTaskIdNull;
68+
return true;
69+
}
70+
}
71+
return false;
72+
}
73+
74+
[[nodiscard]] constexpr bool IsScheduled() const noexcept {
75+
return task_id_ != MessageLoop::kTaskIdNull;
76+
}
77+
78+
[[nodiscard]] constexpr bool operator==(const ScopedTaskId& other) const
79+
noexcept {
80+
return other.task_id_ == task_id_;
81+
}
82+
83+
[[nodiscard]] constexpr bool operator<(const ScopedTaskId& other) const
84+
noexcept {
85+
return task_id_ < other.task_id_;
86+
}
87+
88+
private:
89+
ScopedTaskId(const ScopedTaskId&) = delete;
90+
ScopedTaskId& operator=(const ScopedTaskId&) = delete;
91+
template <typename Callable>
92+
[[nodiscard]] bool PostTask(const base::Location& from_here,
93+
Callable&& callback,
94+
base::TimeDelta delay) noexcept {
95+
if (task_id_ != MessageLoop::kTaskIdNull) {
96+
LOG(ERROR) << "Scheduling another task but task id " << task_id_
97+
<< " isn't executed yet! This can cause the old task to leak.";
98+
return false;
99+
}
100+
task_id_ = MessageLoop::current()->PostDelayedTask(
101+
from_here,
102+
base::BindOnce(&ScopedTaskId::ExecuteTask<decltype(callback)>,
103+
base::Unretained(this),
104+
std::move(callback)),
105+
delay);
106+
return task_id_ != MessageLoop::kTaskIdNull;
107+
}
108+
template <typename Callable>
109+
void ExecuteTask(Callable&& callback) {
110+
task_id_ = MessageLoop::kTaskIdNull;
111+
if constexpr (std::is_same_v<Callable&&, base::OnceClosure&&>) {
112+
std::move(callback).Run();
113+
} else {
114+
std::move(callback)();
115+
}
116+
}
117+
MessageLoop::TaskId task_id_{MessageLoop::kTaskIdNull};
118+
};
119+
} // namespace chromeos_update_engine
120+
121+
#endif

payload_consumer/file_descriptor.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ bool EintrSafeFileDescriptor::Flush() {
139139
}
140140

141141
bool EintrSafeFileDescriptor::Close() {
142-
CHECK_GE(fd_, 0);
142+
if (fd_ < 0) {
143+
return false;
144+
}
143145
// https://stackoverflow.com/questions/705454/does-linux-guarantee-the-contents-of-a-file-is-flushed-to-disc-after-close
144146
// |close()| doesn't imply |fsync()|, we need to do it manually.
145147
fsync(fd_);

0 commit comments

Comments
 (0)