123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- /***********************************************
- File Name: context.h
- Author: Abby Cin
- Mail: abbytsing@gmail.com
- Created Time: 10/24/20 2:43 PM
- ***********************************************/
-
- #ifndef _CONET_CONTEXT_H_
- #define _CONET_CONTEXT_H_
-
- class peer;
- class acceptor;
- class context
- {
- public:
- context() : efd_{-1}, stop_{true}, revs_{1}, conn_{} { efd_ = ::epoll_create1(EPOLL_CLOEXEC); }
- ~context() { cleanup(); }
-
- int run()
- {
- stop_ = false;
- while(!stop_)
- {
- errno = 0;
- int res = ::epoll_wait(efd_, revs_.data(), revs_.size(), -1);
- if(res < 0)
- {
- return res;
- }
- for(int i = 0; i < res; ++i)
- {
- if((revs_[i].events & EPOLLIN) || (revs_[i].events & EPOLLPRI) || (revs_[i].events & EPOLLHUP) ||
- (revs_[i].events & EPOLLERR))
- {
- auto co = conn_.find(revs_[i].data.fd);
- if(co != conn_.end())
- {
- co->second.resume();
- }
- }
- }
- }
- return 0;
- }
-
- void stop()
- {
- stop_ = true;
- cleanup();
- }
-
- bool running() { return !stop_; }
-
- private:
- int efd_;
- std::atomic_bool stop_;
- std::vector<epoll_event> revs_;
- std::map<int, handle_t> conn_;
-
- friend peer;
- friend acceptor;
-
- void cleanup()
- {
- for(auto& [_, v]: conn_)
- {
- v.destroy();
- }
- conn_.clear();
- }
-
- int push(int fd, handle_t co)
- {
- if(!conn_.contains(fd))
- {
- epoll_event ev{};
- ev.data.fd = fd;
- ev.events = EPOLLIN;
- int r = ::epoll_ctl(efd_, EPOLL_CTL_ADD, fd, &ev);
- if(r < 0)
- {
- return r;
- }
- }
- if(conn_.size() + 1 == revs_.size())
- {
- revs_.resize(revs_.size() * 2);
- }
- conn_[fd] = co;
- return 0;
- }
-
- int pop(int fd)
- {
- debug("remove from loop:", fd);
- auto c = conn_.find(fd);
- if(c != conn_.end())
- {
- c->second = nullptr;
- conn_.erase(c);
- }
- epoll_event ev{};
- ev.events = EPOLLIN;
- ev.data.fd = fd;
- return ::epoll_ctl(efd_, EPOLL_CTL_DEL, fd, &ev);
- }
- };
-
- #endif //_CONET_CONTEXT_H_
|