summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-12 08:05:51 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-12 08:05:51 +0000
commitd42484eb53f9528d1751999d80eff9766c7800ca (patch)
tree486624a5001ed592a2ee8fa27e02b125b54f39ab
parente10fe32c163abde837c10ad0f0935b7f02077539 (diff)
parent382e3eadfba95657bb75ffd92773583eedf082ac (diff)
downloadcore-android-security-11.0.0_r53.tar.gz
Merge cherrypicks of [15541536, 15541590, 15541500, 15541501, 15541502, 15541503, 15541504, 15541505, 15541611, 15541508, 15541612, 15541591, 15541265, 15541266, 15541267, 15541614, 15541593] into security-aosp-rvc-releaseandroid-security-11.0.0_r55android-security-11.0.0_r54android-security-11.0.0_r53android-security-11.0.0_r52android-security-11.0.0_r51android-security-11.0.0_r50android-security-11.0.0_r49
Change-Id: I94005764fe846381b9f6ec240d44a67750541934
-rw-r--r--init/Android.bp1
-rw-r--r--init/epoll.cpp12
-rw-r--r--init/epoll.h9
-rw-r--r--init/epoll_test.cpp76
4 files changed, 90 insertions, 8 deletions
diff --git a/init/Android.bp b/init/Android.bp
index 827a8293f..4865694f3 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -239,6 +239,7 @@ cc_test {
srcs: [
"devices_test.cpp",
+ "epoll_test.cpp",
"firmware_handler_test.cpp",
"init_test.cpp",
"keychords_test.cpp",
diff --git a/init/epoll.cpp b/init/epoll.cpp
index 17d63fa5d..74d8aac96 100644
--- a/init/epoll.cpp
+++ b/init/epoll.cpp
@@ -38,11 +38,12 @@ Result<void> Epoll::Open() {
return {};
}
-Result<void> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) {
+Result<void> Epoll::RegisterHandler(int fd, Handler handler, uint32_t events) {
if (!events) {
return Error() << "Must specify events";
}
- auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(handler));
+ auto sp = std::make_shared<decltype(handler)>(std::move(handler));
+ auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(sp));
if (!inserted) {
return Error() << "Cannot specify two epoll handlers for a given FD";
}
@@ -69,7 +70,7 @@ Result<void> Epoll::UnregisterHandler(int fd) {
return {};
}
-Result<std::vector<std::function<void()>*>> Epoll::Wait(
+Result<std::vector<std::shared_ptr<Epoll::Handler>>> Epoll::Wait(
std::optional<std::chrono::milliseconds> timeout) {
int timeout_ms = -1;
if (timeout && timeout->count() < INT_MAX) {
@@ -81,9 +82,10 @@ Result<std::vector<std::function<void()>*>> Epoll::Wait(
if (num_events == -1) {
return ErrnoError() << "epoll_wait failed";
}
- std::vector<std::function<void()>*> pending_functions;
+ std::vector<std::shared_ptr<Handler>> pending_functions;
for (int i = 0; i < num_events; ++i) {
- pending_functions.emplace_back(reinterpret_cast<std::function<void()>*>(ev[i].data.ptr));
+ auto sp = *reinterpret_cast<std::shared_ptr<Handler>*>(ev[i].data.ptr);
+ pending_functions.emplace_back(std::move(sp));
}
return pending_functions;
diff --git a/init/epoll.h b/init/epoll.h
index c32a6614f..0df528935 100644
--- a/init/epoll.h
+++ b/init/epoll.h
@@ -22,6 +22,7 @@
#include <chrono>
#include <functional>
#include <map>
+#include <memory>
#include <optional>
#include <vector>
@@ -36,15 +37,17 @@ class Epoll {
public:
Epoll();
+ typedef std::function<void()> Handler;
+
Result<void> Open();
- Result<void> RegisterHandler(int fd, std::function<void()> handler, uint32_t events = EPOLLIN);
+ Result<void> RegisterHandler(int fd, Handler handler, uint32_t events = EPOLLIN);
Result<void> UnregisterHandler(int fd);
- Result<std::vector<std::function<void()>*>> Wait(
+ Result<std::vector<std::shared_ptr<Handler>>> Wait(
std::optional<std::chrono::milliseconds> timeout);
private:
android::base::unique_fd epoll_fd_;
- std::map<int, std::function<void()>> epoll_handlers_;
+ std::map<int, std::shared_ptr<Handler>> epoll_handlers_;
};
} // namespace init
diff --git a/init/epoll_test.cpp b/init/epoll_test.cpp
new file mode 100644
index 000000000..9236cd53e
--- /dev/null
+++ b/init/epoll_test.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "epoll.h"
+
+#include <sys/unistd.h>
+
+#include <unordered_set>
+
+#include <android-base/file.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace init {
+
+std::unordered_set<void*> sValidObjects;
+
+class CatchDtor final {
+ public:
+ CatchDtor() { sValidObjects.emplace(this); }
+ CatchDtor(const CatchDtor&) { sValidObjects.emplace(this); }
+ ~CatchDtor() {
+ auto iter = sValidObjects.find(this);
+ if (iter != sValidObjects.end()) {
+ sValidObjects.erase(iter);
+ }
+ }
+};
+
+TEST(epoll, UnregisterHandler) {
+ Epoll epoll;
+ ASSERT_RESULT_OK(epoll.Open());
+
+ int fds[2];
+ ASSERT_EQ(pipe(fds), 0);
+
+ CatchDtor catch_dtor;
+ bool handler_invoked;
+ auto handler = [&, catch_dtor]() -> void {
+ auto result = epoll.UnregisterHandler(fds[0]);
+ ASSERT_EQ(result.ok(), !handler_invoked);
+ handler_invoked = true;
+ ASSERT_NE(sValidObjects.find((void*)&catch_dtor), sValidObjects.end());
+ };
+
+ epoll.RegisterHandler(fds[0], std::move(handler));
+
+ uint8_t byte = 0xee;
+ ASSERT_TRUE(android::base::WriteFully(fds[1], &byte, sizeof(byte)));
+
+ auto results = epoll.Wait({});
+ ASSERT_RESULT_OK(results);
+ ASSERT_EQ(results->size(), size_t(1));
+
+ for (const auto& function : *results) {
+ (*function)();
+ (*function)();
+ }
+ ASSERT_TRUE(handler_invoked);
+}
+
+} // namespace init
+} // namespace android