Skip to content

Commit a68b9a1

Browse files
committed
POSIX poll() support
1 parent 5086b56 commit a68b9a1

4 files changed

Lines changed: 248 additions & 109 deletions

File tree

‎Net/Net_vs100.sln‎

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,60 @@
1-
Microsoft Visual Studio Solution File, Format Version 11.00
2-
# Visual Studio 2010
3-
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Net", "Net_vs100.vcxproj", "{B057A1FE-09F7-465E-B8B5-E1B659051D76}"
4-
EndProject
5-
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\TestSuite_vs100.vcxproj", "{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}"
6-
ProjectSection(ProjectDependencies) = postProject
7-
{B057A1FE-09F7-465E-B8B5-E1B659051D76} = {B057A1FE-09F7-465E-B8B5-E1B659051D76}
8-
EndProjectSection
9-
EndProject
10-
Global
11-
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12-
debug_shared|Win32 = debug_shared|Win32
13-
release_shared|Win32 = release_shared|Win32
14-
debug_static_mt|Win32 = debug_static_mt|Win32
15-
release_static_mt|Win32 = release_static_mt|Win32
16-
debug_static_md|Win32 = debug_static_md|Win32
17-
release_static_md|Win32 = release_static_md|Win32
18-
EndGlobalSection
19-
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
21-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_shared|Win32.Build.0 = debug_shared|Win32
22-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
23-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_shared|Win32.ActiveCfg = release_shared|Win32
24-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_shared|Win32.Build.0 = release_shared|Win32
25-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_shared|Win32.Deploy.0 = release_shared|Win32
26-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32
27-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32
28-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32
29-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32
30-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_mt|Win32.Build.0 = release_static_mt|Win32
31-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32
32-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32
33-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_md|Win32.Build.0 = debug_static_md|Win32
34-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32
35-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_md|Win32.ActiveCfg = release_static_md|Win32
36-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_md|Win32.Build.0 = release_static_md|Win32
37-
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_md|Win32.Deploy.0 = release_static_md|Win32
38-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
39-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_shared|Win32.Build.0 = debug_shared|Win32
40-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
41-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_shared|Win32.ActiveCfg = release_shared|Win32
42-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_shared|Win32.Build.0 = release_shared|Win32
43-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_shared|Win32.Deploy.0 = release_shared|Win32
44-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32
45-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32
46-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32
47-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32
48-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_mt|Win32.Build.0 = release_static_mt|Win32
49-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32
50-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32
51-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_md|Win32.Build.0 = debug_static_md|Win32
52-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32
53-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_md|Win32.ActiveCfg = release_static_md|Win32
54-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_md|Win32.Build.0 = release_static_md|Win32
55-
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_md|Win32.Deploy.0 = release_static_md|Win32
56-
EndGlobalSection
57-
GlobalSection(SolutionProperties) = preSolution
58-
HideSolutionNode = FALSE
59-
EndGlobalSection
60-
EndGlobal
1+
Microsoft Visual Studio Solution File, Format Version 11.00
2+
# Visual Studio 2010
3+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Net", "Net_vs100.vcxproj", "{B057A1FE-09F7-465E-B8B5-E1B659051D76}"
4+
EndProject
5+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\TestSuite_vs100.vcxproj", "{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}"
6+
ProjectSection(ProjectDependencies) = postProject
7+
{B057A1FE-09F7-465E-B8B5-E1B659051D76} = {B057A1FE-09F7-465E-B8B5-E1B659051D76}
8+
EndProjectSection
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
debug_shared|Win32 = debug_shared|Win32
13+
debug_static_md|Win32 = debug_static_md|Win32
14+
debug_static_mt|Win32 = debug_static_mt|Win32
15+
release_shared|Win32 = release_shared|Win32
16+
release_static_md|Win32 = release_static_md|Win32
17+
release_static_mt|Win32 = release_static_mt|Win32
18+
EndGlobalSection
19+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
21+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_shared|Win32.Build.0 = debug_shared|Win32
22+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
23+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32
24+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_md|Win32.Build.0 = debug_static_md|Win32
25+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32
26+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32
27+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32
28+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32
29+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_shared|Win32.ActiveCfg = release_shared|Win32
30+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_shared|Win32.Build.0 = release_shared|Win32
31+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_shared|Win32.Deploy.0 = release_shared|Win32
32+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_md|Win32.ActiveCfg = release_static_md|Win32
33+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_md|Win32.Build.0 = release_static_md|Win32
34+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_md|Win32.Deploy.0 = release_static_md|Win32
35+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32
36+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_mt|Win32.Build.0 = release_static_mt|Win32
37+
{B057A1FE-09F7-465E-B8B5-E1B659051D76}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32
38+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
39+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_shared|Win32.Build.0 = debug_shared|Win32
40+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
41+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32
42+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_md|Win32.Build.0 = debug_static_md|Win32
43+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32
44+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32
45+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32
46+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32
47+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_shared|Win32.ActiveCfg = release_shared|Win32
48+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_shared|Win32.Build.0 = release_shared|Win32
49+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_shared|Win32.Deploy.0 = release_shared|Win32
50+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_md|Win32.ActiveCfg = release_static_md|Win32
51+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_md|Win32.Build.0 = release_static_md|Win32
52+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_md|Win32.Deploy.0 = release_static_md|Win32
53+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32
54+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_mt|Win32.Build.0 = release_static_mt|Win32
55+
{D5EFBF27-B934-4B8D-8AE5-6EC00374819C}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32
56+
EndGlobalSection
57+
GlobalSection(SolutionProperties) = preSolution
58+
HideSolutionNode = FALSE
59+
EndGlobalSection
60+
EndGlobal

‎Net/include/Poco/Net/Socket.h‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ class Net_API Socket
142142

143143
bool poll(const Poco::Timespan& timeout, int mode) const;
144144
/// Determines the status of the socket, using a
145-
/// call to select().
145+
/// call to poll() or select().
146146
///
147147
/// The mode argument is constructed by combining the values
148148
/// of the SelectMode enumeration.
@@ -315,6 +315,23 @@ class Net_API Socket
315315
/// Returns the socket descriptor for this socket.
316316

317317
private:
318+
319+
#if defined(POCO_HAVE_FD_POLL)
320+
class FDCompare
321+
/// Utility functor used to compare socket file descriptors.
322+
/// Used in poll() member function.
323+
{
324+
public:
325+
FDCompare(int fd): _fd(fd) { }
326+
inline bool operator()(const Socket& socket) const
327+
{ return socket.sockfd() == _fd; }
328+
329+
private:
330+
FDCompare();
331+
int _fd;
332+
};
333+
#endif
334+
318335
SocketImpl* _pImpl;
319336
};
320337

@@ -604,6 +621,15 @@ inline bool Socket::supportsIPv4()
604621
}
605622

606623

624+
inline bool Socket::supportsIPv6()
625+
{
626+
#if defined(POCO_HAVE_IPv6)
627+
return true;
628+
#else
629+
return false;
630+
#endif
631+
}
632+
607633
} } // namespace Poco::Net
608634

609635

‎Net/src/Socket.cpp‎

Lines changed: 88 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
#include <string.h> // FD_SET needs memset on some platforms, so we can't use <cstring>
4242
#if defined(POCO_HAVE_FD_EPOLL)
4343
#include <sys/epoll.h>
44+
#elif defined(POCO_HAVE_FD_POLL)
45+
#include "Poco/SharedPtr.h"
46+
#include <poll.h>
47+
typedef Poco::SharedPtr<pollfd,
48+
Poco::ReferenceCounter,
49+
Poco::ReleaseArrayPolicy<pollfd> > SharedPollArray;
4450
#endif
4551

4652

@@ -226,6 +232,88 @@ int Socket::select(SocketList& readList, SocketList& writeList, SocketList& exce
226232
std::swap(exceptList, readyExceptList);
227233
return readList.size() + writeList.size() + exceptList.size();
228234

235+
#elif defined(POCO_HAVE_FD_POLL)
236+
237+
nfds_t nfd = readList.size() + writeList.size() + exceptList.size();
238+
if (0 == nfd) return 0;
239+
240+
SharedPollArray pPollArr = new pollfd[nfd];
241+
242+
int idx = 0;
243+
for (SocketList::iterator it = readList.begin(); it != readList.end(); ++it)
244+
{
245+
pPollArr[idx].fd = int(it->sockfd());
246+
pPollArr[idx++].events |= POLLIN;
247+
}
248+
249+
SocketList::iterator begR = readList.begin();
250+
SocketList::iterator endR = readList.end();
251+
for (SocketList::iterator it = writeList.begin(); it != writeList.end(); ++it)
252+
{
253+
SocketList::iterator pos = std::find(begR, endR, *it);
254+
if (pos != endR)
255+
{
256+
pPollArr[pos-begR].events |= POLLOUT;
257+
--nfd;
258+
}
259+
else
260+
{
261+
pPollArr[idx].fd = int(it->sockfd());
262+
pPollArr[idx++].events |= POLLOUT;
263+
}
264+
}
265+
266+
SocketList::iterator begW = writeList.begin();
267+
SocketList::iterator endW = writeList.end();
268+
for (SocketList::iterator it = exceptList.begin(); it != exceptList.end(); ++it)
269+
{
270+
SocketList::iterator pos = std::find(begR, endR, *it);
271+
if (pos != endR) --nfd;
272+
else
273+
{
274+
SocketList::iterator pos = std::find(begW, endW, *it);
275+
if (pos != endW) --nfd;
276+
else pPollArr[idx++].fd = int(it->sockfd());
277+
}
278+
}
279+
280+
Poco::Timespan remainingTime(timeout);
281+
int rc;
282+
do
283+
{
284+
Poco::Timestamp start;
285+
rc = ::poll(pPollArr, nfd, timeout.totalMilliseconds());
286+
if (rc < 0 && SocketImpl::lastError() == POCO_EINTR)
287+
{
288+
Poco::Timestamp end;
289+
Poco::Timespan waited = end - start;
290+
if (waited < remainingTime) remainingTime -= waited;
291+
else remainingTime = 0;
292+
}
293+
}
294+
while (rc < 0 && SocketImpl::lastError() == POCO_EINTR);
295+
if (rc < 0) SocketImpl::error();
296+
297+
SocketList readyReadList;
298+
SocketList readyWriteList;
299+
SocketList readyExceptList;
300+
301+
SocketList::iterator begE = exceptList.begin();
302+
SocketList::iterator endE = exceptList.end();
303+
for (int idx = 0; idx < nfd; ++idx)
304+
{
305+
SocketList::iterator slIt = std::find_if(begR, endR, Socket::FDCompare(pPollArr[idx].fd));
306+
if (POLLIN & pPollArr[idx].revents && slIt != endR) readyReadList.push_back(*slIt);
307+
slIt = std::find_if(begW, endW, Socket::FDCompare(pPollArr[idx].fd));
308+
if (POLLOUT & pPollArr[idx].revents && slIt != endW) readyWriteList.push_back(*slIt);
309+
slIt = std::find_if(begE, endE, Socket::FDCompare(pPollArr[idx].fd));
310+
if (POLLERR & pPollArr[idx].revents && slIt != endE) readyExceptList.push_back(*slIt);
311+
}
312+
std::swap(readList, readyReadList);
313+
std::swap(writeList, readyWriteList);
314+
std::swap(exceptList, readyExceptList);
315+
return readList.size() + writeList.size() + exceptList.size();
316+
229317
#else
230318

231319
fd_set fdRead;
@@ -327,14 +415,4 @@ int Socket::select(SocketList& readList, SocketList& writeList, SocketList& exce
327415
}
328416

329417

330-
bool Socket::supportsIPv6()
331-
{
332-
#if defined(POCO_HAVE_IPv6)
333-
return true;
334-
#else
335-
return false;
336-
#endif
337-
}
338-
339-
340418
} } // namespace Poco::Net

0 commit comments

Comments
 (0)