diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2014-09-13 15:36:27 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2014-09-13 17:33:22 +0900 |
| commit | 596e5c616218c9681adf4eb45077608510e2876e (patch) | |
| tree | be2c7fb20b14f0c4dc533c82dbb5dad23529d693 /src/KqueueEventPoll.cc | |
| parent | f55c16c7edeb319a82217a91a87a35cddfd606b0 (diff) | |
Refactor event poll classes so that we don't have to allocate memory on query
I left Port and libuv classes, since I don't have them compiled.
So they were updated minimally.
Diffstat (limited to 'src/KqueueEventPoll.cc')
| -rw-r--r-- | src/KqueueEventPoll.cc | 111 |
1 files changed, 57 insertions, 54 deletions
diff --git a/src/KqueueEventPoll.cc b/src/KqueueEventPoll.cc index b44e83da..c1b85804 100644 --- a/src/KqueueEventPoll.cc +++ b/src/KqueueEventPoll.cc @@ -89,7 +89,7 @@ size_t KqueueEventPoll::KSocketEntry::getEvents KqueueEventPoll::KqueueEventPoll() : kqEventsSize_(KQUEUE_EVENTS_MAX), - kqEvents_(new struct kevent[kqEventsSize_]) + kqEvents_(make_unique<struct kevent[]>(kqEventsSize_)) { kqfd_ = kqueue(); } @@ -106,7 +106,6 @@ KqueueEventPoll::~KqueueEventPoll() util::safeStrerror(errNum).c_str())); } } - delete [] kqEvents_; } bool KqueueEventPoll::good() const @@ -118,7 +117,8 @@ void KqueueEventPoll::poll(const struct timeval& tv) { struct timespec timeout = { tv.tv_sec, tv.tv_usec*1000 }; int res; - while((res = kevent(kqfd_, kqEvents_, 0, kqEvents_, kqEventsSize_, &timeout)) + while((res = kevent(kqfd_, kqEvents_.get(), 0, kqEvents_.get(), + kqEventsSize_, &timeout)) == -1 && errno == EINTR); if(res > 0) { for(int i = 0; i < res; ++i) { @@ -142,9 +142,10 @@ void KqueueEventPoll::poll(const struct timeval& tv) // their API. So we call ares_process_fd for all ares_channel and // re-register their sockets. for(auto & r : nameResolverEntries_) { - r->processTimeout(); - r->removeSocketEvents(this); - r->addSocketEvents(this); + auto& ent = r.second; + ent.processTimeout(); + ent.removeSocketEvents(this); + ent.addSocketEvents(this); } #endif // ENABLE_ASYNC_DNS @@ -169,24 +170,24 @@ int translateEvents(EventPoll::EventType events) bool KqueueEventPoll::addEvents (sock_t socket, const KqueueEventPoll::KEvent& event) { - std::shared_ptr<KSocketEntry> socketEntry(new KSocketEntry(socket)); - auto i = socketEntries_.lower_bound(socketEntry); + auto i = socketEntries_.lower_bound(socket); int r = 0; struct timespec zeroTimeout = { 0, 0 }; struct kevent changelist[2]; size_t n; - if(i != socketEntries_.end() && *(*i) == *socketEntry) { - event.addSelf(*i); - n = (*i)->getEvents(changelist); + if(i != std::end(socketEntries_) && (*i).first == socket) { + auto& socketEntry = (*i).second; + event.addSelf(&socketEntry); + n = socketEntry.getEvents(changelist); } else { - socketEntries_.insert(i, socketEntry); + i = socketEntries_.insert(i, std::make_pair(socket, KSocketEntry(socket))); + auto& socketEntry = (*i).second; if(socketEntries_.size() > kqEventsSize_) { kqEventsSize_ *= 2; - delete [] kqEvents_; - kqEvents_ = new struct kevent[kqEventsSize_]; + kqEvents_ = make_unique<struct kevent[]>(kqEventsSize_); } - event.addSelf(socketEntry); - n = socketEntry->getEvents(changelist); + event.addSelf(&socketEntry); + n = socketEntry.getEvents(changelist); } r = kevent(kqfd_, changelist, n, changelist, 0, &zeroTimeout); int errNum = errno; @@ -201,7 +202,7 @@ bool KqueueEventPoll::addEvents } bool KqueueEventPoll::addEvents(sock_t socket, Command* command, - EventPoll::EventType events) + EventPoll::EventType events) { int kqEvents = translateEvents(events); return addEvents(socket, KCommandEvent(command, kqEvents)); @@ -216,44 +217,44 @@ bool KqueueEventPoll::addEvents(sock_t socket, Command* command, int events, #endif // ENABLE_ASYNC_DNS bool KqueueEventPoll::deleteEvents(sock_t socket, - const KqueueEventPoll::KEvent& event) + const KqueueEventPoll::KEvent& event) { - std::shared_ptr<KSocketEntry> socketEntry(new KSocketEntry(socket)); - auto i = socketEntries_.find(socketEntry); - if(i == socketEntries_.end()) { + auto i = socketEntries_.find(socket); + if(i == std::end(socketEntries_)) { A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket)); return false; + } + + auto& socketEntry = (*i).second; + event.removeSelf(&socketEntry); + int r = 0; + struct timespec zeroTimeout = { 0, 0 }; + struct kevent changelist[2]; + size_t n = socketEntry.getEvents(changelist); + r = kevent(kqfd_, changelist, n, changelist, 0, &zeroTimeout); + int errNum = errno; + if(socketEntry.eventEmpty()) { + socketEntries_.erase(i); + } + if(r == -1) { + A2_LOG_DEBUG(fmt("Failed to delete socket event:%s", + util::safeStrerror(errNum).c_str())); + return false; } else { - event.removeSelf(*i); - int r = 0; - struct timespec zeroTimeout = { 0, 0 }; - struct kevent changelist[2]; - size_t n = (*i)->getEvents(changelist); - r = kevent(kqfd_, changelist, n, changelist, 0, &zeroTimeout); - int errNum = errno; - if((*i)->eventEmpty()) { - socketEntries_.erase(i); - } - if(r == -1) { - A2_LOG_DEBUG(fmt("Failed to delete socket event:%s", - util::safeStrerror(errNum).c_str())); - return false; - } else { - return true; - } + return true; } } #ifdef ENABLE_ASYNC_DNS bool KqueueEventPoll::deleteEvents(sock_t socket, Command* command, - const std::shared_ptr<AsyncNameResolver>& rs) + const std::shared_ptr<AsyncNameResolver>& rs) { return deleteEvents(socket, KADNSEvent(rs, command, socket, 0)); } #endif // ENABLE_ASYNC_DNS bool KqueueEventPoll::deleteEvents(sock_t socket, Command* command, - EventPoll::EventType events) + EventPoll::EventType events) { int kqEvents = translateEvents(events); return deleteEvents(socket, KCommandEvent(command, kqEvents)); @@ -263,16 +264,17 @@ bool KqueueEventPoll::deleteEvents(sock_t socket, Command* command, bool KqueueEventPoll::addNameResolver (const std::shared_ptr<AsyncNameResolver>& resolver, Command* command) { - std::shared_ptr<KAsyncNameResolverEntry> entry - (new KAsyncNameResolverEntry(resolver, command)); - auto itr = nameResolverEntries_.find(entry); - if(itr == nameResolverEntries_.end()) { - nameResolverEntries_.insert(entry); - entry->addSocketEvents(this); - return true; - } else { + auto key = std::make_pair(resolver.get(), command); + auto itr = nameResolverEntries_.lower_bound(key); + + if(itr != std::end(nameResolverEntries_) && (*itr).first == key) { return false; } + + itr = nameResolverEntries_.insert + (itr, std::make_pair(key, KAsyncNameResolverEntry(resolver, command))); + (*itr).second.addSocketEvents(this); + return true; } bool KqueueEventPoll::deleteNameResolver @@ -280,14 +282,15 @@ bool KqueueEventPoll::deleteNameResolver { std::shared_ptr<KAsyncNameResolverEntry> entry (new KAsyncNameResolverEntry(resolver, command)); - auto itr = nameResolverEntries_.find(entry); - if(itr == nameResolverEntries_.end()) { + auto key = std::make_pair(resolver.get(), command); + auto itr = nameResolverEntries_.find(key); + if(itr == std::end(nameResolverEntries_)) { return false; - } else { - (*itr)->removeSocketEvents(this); - nameResolverEntries_.erase(itr); - return true; } + + (*itr).second.removeSocketEvents(this); + nameResolverEntries_.erase(itr); + return true; } #endif // ENABLE_ASYNC_DNS |
