This commit is contained in:
Alex Fabijanic
2021-04-21 07:47:57 +02:00
parent cd6422fde3
commit b27f440e36
5 changed files with 162 additions and 24 deletions

View File

@@ -263,10 +263,8 @@ public:
if (it->fd == fd)
{
it->events = 0;
if (mode & PollSet::POLL_READ)
it->events |= POLLIN;
if (mode & PollSet::POLL_WRITE)
it->events |= POLLOUT;
it->revents = 0;
setMode(it->fd, it->events, mode);
}
}
}
@@ -307,11 +305,7 @@ public:
pfd.fd = it->first;
pfd.events = 0;
pfd.revents = 0;
if (it->second & PollSet::POLL_READ)
pfd.events |= POLLIN;
if (it->second & PollSet::POLL_WRITE)
pfd.events |= POLLOUT;
setMode(pfd.fd, pfd.events, it->second);
_pollfds.push_back(pfd);
}
_addMap.clear();
@@ -325,9 +319,15 @@ public:
{
Poco::Timestamp start;
#ifdef _WIN32
rc = WSAPoll(&_pollfds[0], static_cast<ULONG>(_pollfds.size()), static_cast<INT>(timeout.totalMilliseconds()));
rc = WSAPoll(&_pollfds[0], static_cast<ULONG>(_pollfds.size()), static_cast<INT>(remainingTime.totalMilliseconds()));
// see https://github.com/pocoproject/poco/issues/3248
if ((remainingTime > 0) && (rc > 0) && !hasSignaledFDs())
{
rc = -1;
WSASetLastError(WSAEINTR);
}
#else
rc = ::poll(&_pollfds[0], _pollfds.size(), timeout.totalMilliseconds());
rc = ::poll(&_pollfds[0], _pollfds.size(), remainingTime.totalMilliseconds());
#endif
if (rc < 0 && SocketImpl::lastError() == POCO_EINTR)
{
@@ -352,16 +352,20 @@ public:
std::map<poco_socket_t, Socket>::const_iterator its = _socketMap.find(it->fd);
if (its != _socketMap.end())
{
if (it->revents & POLLIN)
if ((it->revents & POLLIN)
#ifdef _WIN32
|| (it->revents & POLLHUP)
#endif
)
result[its->second] |= PollSet::POLL_READ;
if (it->revents & POLLOUT)
if ((it->revents & POLLOUT)
#ifdef _WIN32
&& (_wantPOLLOUT.find(it->fd) != _wantPOLLOUT.end())
#endif
)
result[its->second] |= PollSet::POLL_WRITE;
if (it->revents & POLLERR)
result[its->second] |= PollSet::POLL_ERROR;
#ifdef _WIN32
if (it->revents & POLLHUP)
result[its->second] |= PollSet::POLL_READ;
#endif
}
it->revents = 0;
}
@@ -372,8 +376,52 @@ public:
}
private:
#ifdef _WIN32
void setMode(poco_socket_t fd, short& target, int mode)
{
if (mode & PollSet::POLL_READ)
target |= POLLIN;
if (mode & PollSet::POLL_WRITE)
_wantPOLLOUT.insert(fd);
else
_wantPOLLOUT.erase(fd);
target |= POLLOUT;
}
bool hasSignaledFDs()
{
for (const auto& pollfd : _pollfds)
{
if ((pollfd.revents | POLLOUT) &&
(_wantPOLLOUT.find(pollfd.fd) != _wantPOLLOUT.end()))
{
return true;
}
}
return false;
}
#else
void setMode(poco_socket_t fd, short& target, int mode)
{
if (mode & PollSet::POLL_READ)
target |= POLLIN;
if (mode & PollSet::POLL_WRITE)
target |= POLLOUT;
}
#endif
mutable Poco::FastMutex _mutex;
std::map<poco_socket_t, Socket> _socketMap;
#ifdef _WIN32
std::set<poco_socket_t> _wantPOLLOUT;
#endif
std::map<poco_socket_t, int> _addMap;
std::set<poco_socket_t> _removeSet;
std::vector<pollfd> _pollfds;