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();