adb: fdevent: extract Create/Destroy from fdevent_context_poll.

am: 33944a2742

Change-Id: Ie999135e7a60d01848e3ccee13d93135ab2170e8
This commit is contained in:
Josh Gao 2019-07-09 13:38:10 -07:00 committed by android-build-merger
commit 77e1372ad9
4 changed files with 51 additions and 35 deletions

View file

@ -24,6 +24,7 @@
#include <android-base/stringprintf.h>
#include <android-base/threads.h>
#include "adb_utils.h"
#include "fdevent.h"
#include "fdevent_poll.h"
@ -48,6 +49,40 @@ std::string dump_fde(const fdevent* fde) {
state.c_str());
}
fdevent* fdevent_context::Create(unique_fd fd, std::variant<fd_func, fd_func2> func, void* arg) {
CheckMainThread();
CHECK_GE(fd.get(), 0);
fdevent* fde = new fdevent();
fde->id = fdevent_id_++;
fde->state = FDE_ACTIVE;
fde->fd = std::move(fd);
fde->func = func;
fde->arg = arg;
if (!set_file_block_mode(fde->fd, false)) {
// Here is not proper to handle the error. If it fails here, some error is
// likely to be detected by poll(), then we can let the callback function
// to handle it.
LOG(ERROR) << "failed to set non-blocking mode for fd " << fde->fd.get();
}
this->Register(fde);
return fde;
}
unique_fd fdevent_context::Destroy(fdevent* fde) {
CheckMainThread();
if (!fde) {
return {};
}
this->Unregister(fde);
unique_fd result = std::move(fde->fd);
delete fde;
return result;
}
void fdevent_context::CheckMainThread() {
if (main_thread_id_) {
CHECK_EQ(*main_thread_id_, android::base::GetThreadId());

View file

@ -55,11 +55,19 @@ struct fdevent_context {
virtual ~fdevent_context() = default;
// Allocate and initialize a new fdevent object.
virtual fdevent* Create(unique_fd fd, std::variant<fd_func, fd_func2> func, void* arg) = 0;
fdevent* Create(unique_fd fd, std::variant<fd_func, fd_func2> func, void* arg);
// Deallocate an fdevent object, returning the file descriptor that was owned by it.
virtual unique_fd Destroy(fdevent* fde) = 0;
unique_fd Destroy(fdevent* fde);
protected:
// Register an fdevent that is being created by Create with the fdevent_context.
virtual void Register(fdevent* fde) = 0;
// Unregister an fdevent that is being destroyed by Destroy with the fdevent_context.
virtual void Unregister(fdevent* fde) = 0;
public:
// Change which events should cause notifications.
virtual void Set(fdevent* fde, unsigned events) = 0;
virtual void Add(fdevent* fde, unsigned events) = 0;
@ -98,6 +106,7 @@ struct fdevent_context {
std::atomic<bool> terminate_loop_ = false;
private:
uint64_t fdevent_id_ = 0;
std::mutex run_queue_mutex_;
std::deque<std::function<void()>> run_queue_ GUARDED_BY(run_queue_mutex_);
};

View file

@ -78,38 +78,14 @@ fdevent_context_poll::~fdevent_context_poll() {
this->Destroy(this->interrupt_fde_);
}
fdevent* fdevent_context_poll::Create(unique_fd fd, std::variant<fd_func, fd_func2> func,
void* arg) {
CheckMainThread();
CHECK_GE(fd.get(), 0);
fdevent* fde = new fdevent();
fde->id = fdevent_id_++;
fde->state = FDE_ACTIVE;
fde->fd = std::move(fd);
fde->func = func;
fde->arg = arg;
if (!set_file_block_mode(fde->fd, false)) {
// Here is not proper to handle the error. If it fails here, some error is
// likely to be detected by poll(), then we can let the callback function
// to handle it.
LOG(ERROR) << "failed to set non-blocking mode for fd " << fde->fd.get();
}
void fdevent_context_poll::Register(fdevent* fde) {
auto pair = poll_node_map_.emplace(fde->fd.get(), PollNode(fde));
CHECK(pair.second) << "install existing fd " << fde->fd.get();
return fde;
}
unique_fd fdevent_context_poll::Destroy(fdevent* fde) {
CheckMainThread();
if (!fde) {
return {};
}
unique_fd result = std::move(fde->fd);
void fdevent_context_poll::Unregister(fdevent* fde) {
if (fde->state & FDE_ACTIVE) {
poll_node_map_.erase(result.get());
poll_node_map_.erase(fde->fd.get());
if (fde->state & FDE_PENDING) {
pending_list_.remove(fde);
@ -117,9 +93,6 @@ unique_fd fdevent_context_poll::Destroy(fdevent* fde) {
fde->state = 0;
fde->events = 0;
}
delete fde;
return result;
}
void fdevent_context_poll::Set(fdevent* fde, unsigned events) {

View file

@ -48,8 +48,8 @@ struct fdevent_context_poll : public fdevent_context {
fdevent_context_poll();
virtual ~fdevent_context_poll();
virtual fdevent* Create(unique_fd fd, std::variant<fd_func, fd_func2> func, void* arg) final;
virtual unique_fd Destroy(fdevent* fde) final;
virtual void Register(fdevent* fde) final;
virtual void Unregister(fdevent* fde) final;
virtual void Set(fdevent* fde, unsigned events) final;
virtual void Add(fdevent* fde, unsigned events) final;
@ -68,7 +68,6 @@ struct fdevent_context_poll : public fdevent_context {
// That's why we don't need a lock for fdevent.
std::unordered_map<int, PollNode> poll_node_map_;
std::list<fdevent*> pending_list_;
uint64_t fdevent_id_ = 0;
unique_fd interrupt_fd_;
fdevent* interrupt_fde_ = nullptr;