I've updated the patch/pretend-NMU (0.6.5-2.2) to include two additional
changes (patch-4, patch-5 from arch).  patch-4 fixes a bug where a fd
can be removed from the set select() listens to even though there's
still a listener for it, and patch-5 adds error check assertions to the
return values of select() which were previously ignored.  Patches for
these additional changes attached, and the 0.6.5-2.2 pretend-NMU is
available from the same location as the previous one above.
--- orig/sigcx/dispatch.cc
+++ mod/sigcx/dispatch.cc
@@ -22,6 +22,8 @@
 #include <sys/time.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <assert.h>
+#include <errno.h>
 
 #include "sigcx/dispatch.h"
 
@@ -181,6 +183,7 @@
   Guard guard(mutex_);
 
   HandlerID id = get_new_handler_id();
+  ++rd_fd_use_[fd];
   FD_SET(fd, &rd_fds_);
   fd_handlers_.insert(make_pair(id, FileEvent(cb, Read, fd)));
   
@@ -193,6 +196,7 @@
   Guard guard(mutex_);
 
   HandlerID id = get_new_handler_id();
+  ++wr_fd_use_[fd];
   FD_SET(fd, &wr_fds_);
   fd_handlers_.insert(make_pair(id, FileEvent(cb, Write, fd)));
   
@@ -204,6 +208,7 @@
 {
   Guard guard(mutex_);
   HandlerID id = get_new_handler_id();
+  ++ex_fd_use_[fd];
   FD_SET(fd, &ex_fds_);
   fd_handlers_.insert(make_pair(id, FileEvent(cb, Except, fd)));
   
@@ -244,12 +249,18 @@
   {
     FileEvent& fevent = fd_it->second;
     
-    if (fevent.ev == Read && FD_ISSET(fevent.fd, &rd_fds_))
+    if (fevent.ev == Read && --rd_fd_use_[fevent.fd] == 0) {
       FD_CLR(fevent.fd, &rd_fds_);
-    if (fevent.ev == Write && FD_ISSET(fevent.fd, &wr_fds_))
+      rd_fd_use_.erase(fevent.fd);
+    }
+    if (fevent.ev == Write && --wr_fd_use_[fevent.fd] == 0) {
       FD_CLR(fevent.fd, &wr_fds_);
-    if (fevent.ev == Except && FD_ISSET(fevent.fd, &ex_fds_))
+      wr_fd_use_.erase(fevent.fd);
+    }
+    if (fevent.ev == Except && --ex_fd_use_[fevent.fd] == 0) {
       FD_CLR(fevent.fd, &ex_fds_);
+      ex_fd_use_.erase(fevent.fd);
+    }
     
     fevent.deleted = true;
   }


--- orig/sigcx/dispatch.h
+++ mod/sigcx/dispatch.h
@@ -221,6 +221,7 @@
     typedef std::multimap<TimerEvent, HandlerID> TMEventMap;
     typedef std::map<HandlerID, TMEventMap::iterator> TMHandlerMap;
     typedef std::map<HandlerID, FileEvent> FDHandlerMap;
+    typedef std::map<int, int> FDUseMap;
     Threads::Mutex mutex_;
     
     
@@ -228,6 +229,10 @@
     TMEventMap tm_events_;
     FDHandlerMap fd_handlers_;
     fd_set rd_fds_, wr_fds_, ex_fds_;
+    FDUseMap rd_fd_use_;
+    FDUseMap wr_fd_use_;
+    FDUseMap ex_fd_use_;
+
     bool do_exit_;
 };
 



--- orig/sigcx/dispatch.cc
+++ mod/sigcx/dispatch.cc
@@ -360,7 +360,8 @@
     if (tm_events_.size() == 0)
     {
       UnGuard unguard (mutex_);
-      select(FD_SETSIZE, &rd, &wr, &ex, 0);
+      int result = select(FD_SETSIZE, &rd, &wr, &ex, 0);
+      assert(result != -1 || errno == EINTR);
     }
     else
     {
@@ -376,7 +377,8 @@
       tv.tv_sec = timeout.tv_sec;
       tv.tv_usec = timeout.tv_usec;
       
-      select(FD_SETSIZE, &rd, &wr, &ex, &tv);
+      int result = select(FD_SETSIZE, &rd, &wr, &ex, &tv);
+      assert(result != -1 || errno == EINTR);
     }
 
     // check after select, we might have caught a signal



Reply via email to