From 008d5245ef29bb8c34fb1927d431ffe53fbf6a76 Mon Sep 17 00:00:00 2001 From: Avi Kivity <avi@cloudius-systems.com> Date: Tue, 3 Dec 2013 18:18:52 +0200 Subject: [PATCH] epoll: convert to a derived class of file Signed-off-by: Avi Kivity <avi@cloudius-systems.com> --- core/epoll.cc | 74 ++++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 54 deletions(-) diff --git a/core/epoll.cc b/core/epoll.cc index 59e3fa707..f8c220f10 100644 --- a/core/epoll.cc +++ b/core/epoll.cc @@ -64,16 +64,16 @@ inline uint32_t events_poll_to_epoll(uint32_t e) return e; } -class epoll_obj { +class epoll_file final : public file { std::unordered_map<file*, epoll_event> map; - file* epoll_fp; public: - void set_epoll_fp(file* fp) { epoll_fp = fp; } - ~epoll_obj() { + epoll_file() : file(0, DTYPE_UNSPEC) {} + virtual int close() override { for (auto& e : map) { auto fp = e.first; remove_me(fp); } + return 0; } int add(file* fp, struct epoll_event *event) { @@ -85,7 +85,7 @@ public: if (!fp->f_epolls) { fp->f_epolls.reset(new std::vector<file*>); } - fp->f_epolls->push_back(epoll_fp); + fp->f_epolls->push_back(this); } return 0; } @@ -136,52 +136,21 @@ public: private: void remove_me(file* fp) { WITH_LOCK(fp->f_lock) { - auto i = boost::range::find(*fp->f_epolls, epoll_fp); + auto i = boost::range::find(*fp->f_epolls, this); assert(i != fp->f_epolls->end()); fp->f_epolls->erase(i); } } +public: + virtual int read(uio* data, int flags) override { return unsupported_read(this, data, flags); } + virtual int write(uio* data, int flags) override { return unsupported_write(this, data, flags); } + virtual int truncate(off_t off) override { return unsupported_truncate(this, off); } + virtual int ioctl(ulong com, void* data) override { return unsupported_ioctl(this, com, data); } + virtual int stat(struct stat* buf) override { return unsupported_stat(this, buf); } + virtual int chmod(mode_t mode) override { return unsupported_chmod(this, mode); } + virtual int poll(int events) override { return unsupported_poll(this, events); } }; -static int epoll_fop_init(file* f) -{ - return 0; -} - -static int epoll_fop_close(file *f) -{ - delete static_cast<epoll_obj*>(f->f_data); - f->f_data = nullptr; - return 0; -} - -static fileops epoll_ops = { - epoll_fop_init, - unsupported_read, - unsupported_write, - unsupported_truncate, - unsupported_ioctl, - unsupported_poll, - unsupported_stat, - epoll_fop_close, - unsupported_chmod, -}; - -static inline bool is_epoll(struct file *f) -{ - return f->f_ops == &epoll_ops; -} - - -static inline epoll_obj *get_epoll_obj(fileref fr) { - struct file *f = fr.get(); - if (is_epoll(f)) { - return static_cast<epoll_obj*> (f->f_data); - } else { - return nullptr; - } -} - int epoll_create(int size) { // Note we ignore the size parameter. There's no point in checking it's @@ -195,10 +164,7 @@ int epoll_create1(int flags) flags &= ~EPOLL_CLOEXEC; assert(!flags); try { - std::unique_ptr<epoll_obj> s{new epoll_obj}; - fileref f = make_file(0 , DTYPE_UNSPEC, s.get(), &epoll_ops); - s->set_epoll_fp(f.get()); - s.release(); + fileref f = make_file<epoll_file>(); fdesc fd(f); trace_epoll_create(fd.get()); return fd.release(); @@ -221,7 +187,7 @@ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) return -1; } - epoll_obj *epo = get_epoll_obj(epfr); + auto epo = dynamic_cast<epoll_file*>(epfr.get()); if (!epo) { errno = EINVAL; return -1; @@ -261,7 +227,7 @@ int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout_ return -1; } - epoll_obj *epo = get_epoll_obj(epfr); + auto epo = dynamic_cast<epoll_file*>(epfr.get()); if (!epo || maxevents <= 0) { errno = EINVAL; return -1; @@ -270,9 +236,9 @@ int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout_ return epo->wait(events, maxevents, timeout_ms); } -void epoll_file_closed(file* epoll_file, file* client) +void epoll_file_closed(file* epoll_fd, file* client) { - fileref epoll_ptr(epoll_file); - auto epoll_obj = get_epoll_obj(epoll_ptr); + fileref epoll_ptr(epoll_fd); + auto epoll_obj = dynamic_cast<epoll_file*>(epoll_ptr.get()); epoll_obj->del(client); } -- GitLab