Merge "init: Always reap processes before handling properties"
am: 0589aa4265
Change-Id: I825598315caa2a6fe592f293815adf8242f0a644
This commit is contained in:
commit
3f5cc2dd84
4 changed files with 32 additions and 15 deletions
|
|
@ -69,19 +69,24 @@ Result<void> Epoll::UnregisterHandler(int fd) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> Epoll::Wait(std::optional<std::chrono::milliseconds> timeout) {
|
Result<std::vector<std::function<void()>*>> Epoll::Wait(
|
||||||
|
std::optional<std::chrono::milliseconds> timeout) {
|
||||||
int timeout_ms = -1;
|
int timeout_ms = -1;
|
||||||
if (timeout && timeout->count() < INT_MAX) {
|
if (timeout && timeout->count() < INT_MAX) {
|
||||||
timeout_ms = timeout->count();
|
timeout_ms = timeout->count();
|
||||||
}
|
}
|
||||||
epoll_event ev;
|
const auto max_events = epoll_handlers_.size();
|
||||||
auto nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_, &ev, 1, timeout_ms));
|
epoll_event ev[max_events];
|
||||||
if (nr == -1) {
|
auto num_events = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_, ev, max_events, timeout_ms));
|
||||||
|
if (num_events == -1) {
|
||||||
return ErrnoError() << "epoll_wait failed";
|
return ErrnoError() << "epoll_wait failed";
|
||||||
} else if (nr == 1) {
|
|
||||||
std::invoke(*reinterpret_cast<std::function<void()>*>(ev.data.ptr));
|
|
||||||
}
|
}
|
||||||
return {};
|
std::vector<std::function<void()>*> pending_functions;
|
||||||
|
for (int i = 0; i < num_events; ++i) {
|
||||||
|
pending_functions.emplace_back(reinterpret_cast<std::function<void()>*>(ev[i].data.ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
return pending_functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace init
|
} // namespace init
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _INIT_EPOLL_H
|
#pragma once
|
||||||
#define _INIT_EPOLL_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
|
@ -24,6 +23,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <android-base/unique_fd.h>
|
#include <android-base/unique_fd.h>
|
||||||
|
|
||||||
|
|
@ -39,7 +39,8 @@ class Epoll {
|
||||||
Result<void> Open();
|
Result<void> Open();
|
||||||
Result<void> RegisterHandler(int fd, std::function<void()> handler, uint32_t events = EPOLLIN);
|
Result<void> RegisterHandler(int fd, std::function<void()> handler, uint32_t events = EPOLLIN);
|
||||||
Result<void> UnregisterHandler(int fd);
|
Result<void> UnregisterHandler(int fd);
|
||||||
Result<void> Wait(std::optional<std::chrono::milliseconds> timeout);
|
Result<std::vector<std::function<void()>*>> Wait(
|
||||||
|
std::optional<std::chrono::milliseconds> timeout);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
android::base::unique_fd epoll_fd_;
|
android::base::unique_fd epoll_fd_;
|
||||||
|
|
@ -48,5 +49,3 @@ class Epoll {
|
||||||
|
|
||||||
} // namespace init
|
} // namespace init
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -787,8 +787,17 @@ int SecondStageMain(int argc, char** argv) {
|
||||||
if (am.HasMoreCommands()) epoll_timeout = 0ms;
|
if (am.HasMoreCommands()) epoll_timeout = 0ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto result = epoll.Wait(epoll_timeout); !result) {
|
auto pending_functions = epoll.Wait(epoll_timeout);
|
||||||
LOG(ERROR) << result.error();
|
if (!pending_functions) {
|
||||||
|
LOG(ERROR) << pending_functions.error();
|
||||||
|
} else if (!pending_functions->empty()) {
|
||||||
|
// We always reap children before responding to the other pending functions. This is to
|
||||||
|
// prevent a race where other daemons see that a service has exited and ask init to
|
||||||
|
// start it again via ctl.start before init has reaped it.
|
||||||
|
ReapAnyOutstandingChildren();
|
||||||
|
for (const auto& function : *pending_functions) {
|
||||||
|
(*function)();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,11 @@ TestFrame::TestFrame(const std::vector<const std::vector<int>>& chords, EventHan
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestFrame::RelaxForMs(std::chrono::milliseconds wait) {
|
void TestFrame::RelaxForMs(std::chrono::milliseconds wait) {
|
||||||
epoll_.Wait(wait);
|
auto pending_functions = epoll_.Wait(wait);
|
||||||
|
ASSERT_TRUE(pending_functions) << pending_functions.error();
|
||||||
|
for (const auto& function : *pending_functions) {
|
||||||
|
(*function)();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestFrame::SetChord(int key, bool value) {
|
void TestFrame::SetChord(int key, bool value) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue