From 811c0f758da0d161b278fc6b0da333459dd220b4 Mon Sep 17 00:00:00 2001
From: Nils Maier <maierman@web.de>
Date: Fri, 12 Dec 2014 12:21:13 +0100
Subject: [PATCH] Port poll changes to LibuvEventPoll

---
 src/LibuvEventPoll.cc | 45 ++++++++++++++++++++++++-------------------
 src/LibuvEventPoll.h  | 12 +++++++-----
 2 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/src/LibuvEventPoll.cc b/src/LibuvEventPoll.cc
index 3fc76fda..c5b3f42d 100644
--- a/src/LibuvEventPoll.cc
+++ b/src/LibuvEventPoll.cc
@@ -229,11 +229,11 @@ void LibuvEventPoll::pollCallback(KPoll* poll, int status, int events)
 bool LibuvEventPoll::addEvents(sock_t socket,
                                const LibuvEventPoll::KEvent& event)
 {
-  auto socketEntry = std::make_shared<KSocketEntry>(socket);
-  auto i = socketEntries_.lower_bound(socketEntry);
+  auto i = socketEntries_.lower_bound(socket);
 
-  if (i != socketEntries_.end() && **i == *socketEntry) {
-    event.addSelf((*i).get());
+  if (i != socketEntries_.end() && i->first == socket) {
+    auto& socketEntry = i->second;
+    event.addSelf(&socketEntry);
     auto poll = polls_.find(socket);
     if (poll == polls_.end()) {
       throw std::logic_error("Invalid socket");
@@ -242,9 +242,10 @@ bool LibuvEventPoll::addEvents(sock_t socket,
     return true;
   }
 
-  socketEntries_.insert(i, socketEntry);
-  event.addSelf(socketEntry.get());
-  auto poll = new KPoll(this, socketEntry.get(), socket);
+  i = socketEntries_.insert(i, std::make_pair(socket, KSocketEntry(socket)));
+  auto& socketEntry = i->second;
+  event.addSelf(&socketEntry);
+  auto poll = new KPoll(this, &socketEntry, socket);
   polls_[socket] = poll;
   poll->start();
   return true;
@@ -267,22 +268,22 @@ bool LibuvEventPoll::addEvents(sock_t socket, Command* command, int events,
 bool LibuvEventPoll::deleteEvents(sock_t socket,
                                   const LibuvEventPoll::KEvent& event)
 {
-  auto socketEntry = std::make_shared<KSocketEntry>(socket);
-  auto i = socketEntries_.find(socketEntry);
+  auto i = socketEntries_.find(socket);
 
   if (i == socketEntries_.end()) {
     A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
     return false;
   }
 
-  event.removeSelf((*i).get());
+  auto& socketEntry = (*i).second;
+  event.removeSelf(&socketEntry);
 
   auto poll = polls_.find(socket);
   if (poll == polls_.end()) {
     return false;
   }
 
-  if ((*i)->eventEmpty()) {
+  if (socketEntry.eventEmpty()) {
     poll->second->close();
     polls_.erase(poll);
     socketEntries_.erase(i);
@@ -312,25 +313,29 @@ bool LibuvEventPoll::deleteEvents(sock_t socket, Command* command,
 bool LibuvEventPoll::addNameResolver(const std::shared_ptr<AsyncNameResolver>& resolver,
                                      Command* command)
 {
-  auto entry = std::make_shared<KAsyncNameResolverEntry>(resolver, command);
-  auto itr = nameResolverEntries_.lower_bound(entry);
-  if (itr != nameResolverEntries_.end() && *(*itr) == *entry) {
+  auto key = std::make_pair(resolver.get(), command);
+  auto itr = nameResolverEntries_.lower_bound(key);
+
+  if(itr != std::end(nameResolverEntries_) && (*itr).first == key) {
     return false;
   }
-  nameResolverEntries_.insert(itr, entry);
-  entry->addSocketEvents(this);
+
+  itr = nameResolverEntries_.insert
+    (itr, std::make_pair(key, KAsyncNameResolverEntry(resolver, command)));
+  (*itr).second.addSocketEvents(this);
   return true;
 }
 
 bool LibuvEventPoll::deleteNameResolver(const std::shared_ptr<AsyncNameResolver>& resolver,
                                         Command* command)
 {
-  auto entry = std::make_shared<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;
   }
-  (*itr)->removeSocketEvents(this);
+
+  (*itr).second.removeSocketEvents(this);
   nameResolverEntries_.erase(itr);
   return true;
 }
diff --git a/src/LibuvEventPoll.h b/src/LibuvEventPoll.h
index b56b9afb..69fa6a88 100644
--- a/src/LibuvEventPoll.h
+++ b/src/LibuvEventPoll.h
@@ -66,6 +66,10 @@ private:
   class KSocketEntry: public SocketEntry<KCommandEvent, KADNSEvent> {
   public:
     KSocketEntry(sock_t socket);
+
+    KSocketEntry(const KSocketEntry&) = delete;
+    KSocketEntry(KSocketEntry&&) = default;
+
     int getEvents() const;
   };
 
@@ -105,15 +109,13 @@ private:
     }
   };
 
-  typedef std::set<std::shared_ptr<KSocketEntry>,
-                   DerefLess<std::shared_ptr<KSocketEntry> > > KSocketEntrySet;
+  typedef std::map<sock_t, KSocketEntry> KSocketEntrySet;
 
   typedef std::map<sock_t, KPoll*> KPolls;
 
 #ifdef ENABLE_ASYNC_DNS
-  typedef std::set<std::shared_ptr<KAsyncNameResolverEntry>,
-                   DerefLess<std::shared_ptr<KAsyncNameResolverEntry> > >
-  KAsyncNameResolverEntrySet;
+  typedef std::map<std::pair<AsyncNameResolver*, Command*>,
+                   KAsyncNameResolverEntry> KAsyncNameResolverEntrySet;
 #endif // ENABLE_ASYNC_DNS
 
   uv_loop_t* loop_;