diff --git a/adb/fdevent/fdevent.cpp b/adb/fdevent/fdevent.cpp index 562f5872d..fd550200f 100644 --- a/adb/fdevent/fdevent.cpp +++ b/adb/fdevent/fdevent.cpp @@ -63,7 +63,10 @@ fdevent* fdevent_context::Create(unique_fd fd, std::variant f int fd_num = fd.get(); - fdevent* fde = new fdevent(); + auto [it, inserted] = this->installed_fdevents_.emplace(fd_num, fdevent{}); + CHECK(inserted); + + fdevent* fde = &it->second; fde->id = fdevent_id_++; fde->state = 0; fde->fd = std::move(fd); @@ -76,10 +79,6 @@ fdevent* fdevent_context::Create(unique_fd fd, std::variant f LOG(ERROR) << "failed to set non-blocking mode for fd " << fde->fd.get(); } - auto [it, inserted] = this->installed_fdevents_.emplace(fd_num, fde); - CHECK(inserted); - UNUSED(it); - this->Register(fde); return fde; } @@ -92,12 +91,12 @@ unique_fd fdevent_context::Destroy(fdevent* fde) { this->Unregister(fde); - auto erased = this->installed_fdevents_.erase(fde->fd.get()); + unique_fd fd = std::move(fde->fd); + + auto erased = this->installed_fdevents_.erase(fd.get()); CHECK_EQ(1UL, erased); - unique_fd result = std::move(fde->fd); - delete fde; - return result; + return fd; } void fdevent_context::Add(fdevent* fde, unsigned events) { @@ -123,9 +122,9 @@ std::optional fdevent_context::CalculatePollDuration( for (const auto& [fd, fde] : this->installed_fdevents_) { UNUSED(fd); - auto timeout_opt = fde->timeout; + auto timeout_opt = fde.timeout; if (timeout_opt) { - auto deadline = fde->last_active + *timeout_opt; + auto deadline = fde.last_active + *timeout_opt; auto time_left = duration_cast(deadline - now); if (time_left < 0ms) { time_left = 0ms; @@ -194,11 +193,13 @@ static std::unique_ptr fdevent_create_context() { #endif } -static auto& g_ambient_fdevent_context = - *new std::unique_ptr(fdevent_create_context()); +static auto& g_ambient_fdevent_context() { + static auto context = fdevent_create_context().release(); + return context; +} static fdevent_context* fdevent_get_ambient() { - return g_ambient_fdevent_context.get(); + return g_ambient_fdevent_context(); } fdevent* fdevent_create(int fd, fd_func func, void* arg) { @@ -256,5 +257,6 @@ size_t fdevent_installed_count() { } void fdevent_reset() { - g_ambient_fdevent_context = fdevent_create_context(); + auto old = std::exchange(g_ambient_fdevent_context(), fdevent_create_context().release()); + delete old; } diff --git a/adb/fdevent/fdevent.h b/adb/fdevent/fdevent.h index 86814d7c5..9fc3b2c0c 100644 --- a/adb/fdevent/fdevent.h +++ b/adb/fdevent/fdevent.h @@ -52,6 +52,20 @@ struct fdevent_event { unsigned events; }; +struct fdevent final { + uint64_t id; + + unique_fd fd; + int force_eof = 0; + + uint16_t state = 0; + std::optional timeout; + std::chrono::steady_clock::time_point last_active; + + std::variant func; + void* arg = nullptr; +}; + struct fdevent_context { public: virtual ~fdevent_context() = default; @@ -113,7 +127,7 @@ struct fdevent_context { std::atomic terminate_loop_ = false; protected: - std::unordered_map installed_fdevents_; + std::unordered_map installed_fdevents_; private: uint64_t fdevent_id_ = 0; @@ -121,20 +135,6 @@ struct fdevent_context { std::deque> run_queue_ GUARDED_BY(run_queue_mutex_); }; -struct fdevent { - uint64_t id; - - unique_fd fd; - int force_eof = 0; - - uint16_t state = 0; - std::optional timeout; - std::chrono::steady_clock::time_point last_active; - - std::variant func; - void* arg = nullptr; -}; - // Backwards compatibility shims that forward to the global fdevent_context. fdevent* fdevent_create(int fd, fd_func func, void* arg); fdevent* fdevent_create(int fd, fd_func2 func, void* arg); diff --git a/adb/fdevent/fdevent_epoll.cpp b/adb/fdevent/fdevent_epoll.cpp index e3d167424..4ef41d1ee 100644 --- a/adb/fdevent/fdevent_epoll.cpp +++ b/adb/fdevent/fdevent_epoll.cpp @@ -155,15 +155,15 @@ void fdevent_context_epoll::Loop() { event_map[fde] = events; } - for (const auto& [fd, fde] : installed_fdevents_) { + for (auto& [fd, fde] : installed_fdevents_) { unsigned events = 0; - if (auto it = event_map.find(fde); it != event_map.end()) { + if (auto it = event_map.find(&fde); it != event_map.end()) { events = it->second; } if (events == 0) { - if (fde->timeout) { - auto deadline = fde->last_active + *fde->timeout; + if (fde.timeout) { + auto deadline = fde.last_active + *fde.timeout; if (deadline < post_poll) { events |= FDE_TIMEOUT; } @@ -171,13 +171,13 @@ void fdevent_context_epoll::Loop() { } if (events != 0) { - LOG(DEBUG) << dump_fde(fde) << " got events " << std::hex << std::showbase + LOG(DEBUG) << dump_fde(&fde) << " got events " << std::hex << std::showbase << events; - fde_events.push_back({fde, events}); - fde->last_active = post_poll; + fde_events.push_back({&fde, events}); + fde.last_active = post_poll; } } - this->HandleEvents(std::move(fde_events)); + this->HandleEvents(fde_events); fde_events.clear(); } diff --git a/adb/fdevent/fdevent_epoll.h b/adb/fdevent/fdevent_epoll.h index 684fa32bc..6214d2e27 100644 --- a/adb/fdevent/fdevent_epoll.h +++ b/adb/fdevent/fdevent_epoll.h @@ -47,12 +47,7 @@ struct fdevent_context_epoll final : public fdevent_context { protected: virtual void Interrupt() final; - public: - // All operations to fdevent should happen only in the main thread. - // That's why we don't need a lock for fdevent. - std::unordered_map epoll_node_map_; - std::list pending_list_; - + private: unique_fd epoll_fd_; unique_fd interrupt_fd_; fdevent* interrupt_fde_ = nullptr; diff --git a/adb/fdevent/fdevent_poll.cpp b/adb/fdevent/fdevent_poll.cpp index cc4a7a151..ac86c08e1 100644 --- a/adb/fdevent/fdevent_poll.cpp +++ b/adb/fdevent/fdevent_poll.cpp @@ -103,24 +103,27 @@ static std::string dump_pollfds(const std::vector& pollfds) { void fdevent_context_poll::Loop() { main_thread_id_ = android::base::GetThreadId(); + std::vector pollfds; + std::vector poll_events; + while (true) { if (terminate_loop_) { break; } D("--- --- waiting for events"); - std::vector pollfds; + pollfds.clear(); for (const auto& [fd, fde] : this->installed_fdevents_) { adb_pollfd pfd; pfd.fd = fd; pfd.events = 0; - if (fde->state & FDE_READ) { + if (fde.state & FDE_READ) { pfd.events |= POLLIN; } - if (fde->state & FDE_WRITE) { + if (fde.state & FDE_WRITE) { pfd.events |= POLLOUT; } - if (fde->state & FDE_ERROR) { + if (fde.state & FDE_ERROR) { pfd.events |= POLLERR; } #if defined(__linux__) @@ -147,7 +150,6 @@ void fdevent_context_poll::Loop() { } auto post_poll = std::chrono::steady_clock::now(); - std::vector poll_events; for (const auto& pollfd : pollfds) { unsigned events = 0; @@ -170,7 +172,7 @@ void fdevent_context_poll::Loop() { auto it = this->installed_fdevents_.find(pollfd.fd); CHECK(it != this->installed_fdevents_.end()); - fdevent* fde = it->second; + fdevent* fde = &it->second; if (events == 0) { if (fde->timeout) { @@ -187,7 +189,8 @@ void fdevent_context_poll::Loop() { fde->last_active = post_poll; } } - this->HandleEvents(std::move(poll_events)); + this->HandleEvents(poll_events); + poll_events.clear(); } main_thread_id_.reset();