From 276d77ee9d82f843e02689c8242df9fb655c676f Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Sun, 5 Jul 2009 03:46:07 +0000
Subject: [PATCH] 2009-07-05  Tatsuhiro Tsujikawa 
 <t-tujikawa@users.sourceforge.net>

	Winsock select() doesn't work if no socket is in FD_SET.  To
	overcome this problem, a dummy socket is added to FD_SET and it is
	given to select().
	* src/SelectEventPoll.cc
	* src/SelectEventPoll.h
---
 ChangeLog              |  8 ++++++++
 src/SelectEventPoll.cc | 27 ++++++++++++++++++++++++++-
 src/SelectEventPoll.h  |  6 ++++++
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 48e1d6be..496d7322 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-07-05  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Winsock select() doesn't work if no socket is in FD_SET.  To
+	overcome this problem, a dummy socket is added to FD_SET and it is
+	given to select().
+	* src/SelectEventPoll.cc
+	* src/SelectEventPoll.h
+
 2009-07-05  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Disabled --use-head option by default because --use-head=true
diff --git a/src/SelectEventPoll.cc b/src/SelectEventPoll.cc
index 3021ca57..2f1446fc 100644
--- a/src/SelectEventPoll.cc
+++ b/src/SelectEventPoll.cc
@@ -34,6 +34,9 @@
 /* copyright --> */
 #include "SelectEventPoll.h"
 
+#ifdef __MINGW32__
+# include <cassert>
+#endif // __MINGW32__
 #include <cstring>
 #include <algorithm>
 #include <numeric>
@@ -148,10 +151,19 @@ void SelectEventPoll::AsyncNameResolverEntry::process
 
 SelectEventPoll::SelectEventPoll():_logger(LogFactory::getInstance())
 {
+#ifdef __MINGW32__
+  _dummySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  assert(_dummySocket != -1);
+#endif // __MINGW32__
   updateFdSet();
 }
 
-SelectEventPoll::~SelectEventPoll() {}
+SelectEventPoll::~SelectEventPoll()
+{
+#ifdef __MINGW32__
+  ::closesocket(_dummySocket);
+#endif // __MINGW32__
+}
 
 void SelectEventPoll::poll(const struct timeval& tv)
 {
@@ -160,6 +172,11 @@ void SelectEventPoll::poll(const struct timeval& tv)
   
   memcpy(&rfds, &_rfdset, sizeof(fd_set));
   memcpy(&wfds, &_wfdset, sizeof(fd_set));
+#ifdef __MINGW32__
+  fd_set efds;
+  FD_ZERO(&efds);
+  FD_SET(_dummySocket, &efds);
+#endif // __MINGW32__
 #ifdef ENABLE_ASYNC_DNS
 
   for(std::deque<SharedHandle<AsyncNameResolverEntry> >::iterator itr =
@@ -177,7 +194,11 @@ void SelectEventPoll::poll(const struct timeval& tv)
   int retval;
   do {
     struct timeval ttv = tv;
+#ifdef __MINGW32__
+    retval = select(_fdmax+1, &rfds, &wfds, &efds, &ttv);
+#else // !__MINGW32__
     retval = select(_fdmax+1, &rfds, &wfds, NULL, &ttv);
+#endif // !__MINGW32__
   } while(retval == -1 && errno == EINTR);
   if(retval > 0) {
     for(std::deque<SharedHandle<SocketEntry> >::iterator i =
@@ -204,7 +225,11 @@ void SelectEventPoll::poll(const struct timeval& tv)
 
 void SelectEventPoll::updateFdSet()
 {
+#ifdef __MINGW32__
+  _fdmax = _dummySocket;
+#else // !__MINGW32__
   _fdmax = 0;
+#endif // !__MINGW32__
   FD_ZERO(&_rfdset);
   FD_ZERO(&_wfdset);
   for(std::deque<SharedHandle<SocketEntry> >::iterator i =
diff --git a/src/SelectEventPoll.h b/src/SelectEventPoll.h
index 5eaef4cb..a60b7a6b 100644
--- a/src/SelectEventPoll.h
+++ b/src/SelectEventPoll.h
@@ -162,6 +162,12 @@ private:
   std::deque<SharedHandle<AsyncNameResolverEntry> > _nameResolverEntries;
 #endif // ENABLE_ASYNC_DNS
 
+#ifdef __MINGW32__
+  // Winsock select() doesn't work if no socket is in FD_SET. We add
+  // this dummy socket to work around this problem
+  sock_t _dummySocket;
+#endif // __MINGW32__
+
   Logger* _logger;
 
   void updateFdSet();