|
5 | 5 | #include <eepp/network/tcpsocket.hpp> |
6 | 6 | #include <eepp/system/clock.hpp> |
7 | 7 | #include <eepp/system/log.hpp> |
8 | | - |
| 8 | +#include <limits> |
| 9 | + |
9 | 10 | #if EE_PLATFORM == EE_PLATFORM_HAIKU |
10 | 11 | #include <sys/select.h> |
11 | 12 | #endif |
| 13 | + |
| 14 | +#if EE_PLATFORM != EE_PLATFORM_WIN |
| 15 | +#include <poll.h> |
| 16 | +#endif |
12 | 17 |
|
13 | 18 | #ifdef _MSC_VER |
14 | 19 | #pragma warning( disable \ |
@@ -127,30 +132,37 @@ Socket::Status TcpSocket::connect( const IpAddress& remoteAddress, unsigned shor |
127 | 132 | if ( !blocking ) |
128 | 133 | return status; |
129 | 134 |
|
130 | | - // Otherwise, wait until something happens to our socket (success, timeout or error) |
131 | | - if ( status == Socket::NotReady ) { |
132 | | - #if EE_PLATFORM != EE_PLATFORM_WIN |
133 | | - if ( getHandle() >= FD_SETSIZE ) { |
134 | | - // The socket FD is too large for select(). |
135 | | - // You cannot safely use FD_SET. |
136 | | - setBlocking( true ); |
137 | | - return Error; |
138 | | - } |
139 | | - #endif |
140 | | - |
141 | | - // Setup the selector |
142 | | - fd_set selector; |
143 | | - FD_ZERO( &selector ); |
144 | | - FD_SET( getHandle(), &selector ); |
| 135 | + // Otherwise, wait until something happens to our socket (success, timeout or error) |
| 136 | + if ( status == Socket::NotReady ) { |
| 137 | +#if EE_PLATFORM == EE_PLATFORM_WIN |
| 138 | + // Setup the selector |
| 139 | + fd_set selector; |
| 140 | + FD_ZERO( &selector ); |
| 141 | + FD_SET( getHandle(), &selector ); |
145 | 142 |
|
146 | 143 | // Setup the timeout |
147 | 144 | timeval time; |
148 | 145 | time.tv_sec = static_cast<long>( timeout.asMicroseconds() / 1000000 ); |
149 | 146 | time.tv_usec = static_cast<long>( timeout.asMicroseconds() % 1000000 ); |
150 | 147 |
|
151 | | - // Wait for something to write on our socket (which means that the connection request |
152 | | - // has returned) |
153 | | - if ( select( static_cast<int>( getHandle() + 1 ), NULL, &selector, NULL, &time ) > 0 ) { |
| 148 | + // Wait for something to write on our socket (which means that the connection request |
| 149 | + // has returned) |
| 150 | + if ( select( static_cast<int>( getHandle() + 1 ), NULL, &selector, NULL, &time ) > 0 ) { |
| 151 | +#else |
| 152 | + pollfd descriptor; |
| 153 | + descriptor.fd = getHandle(); |
| 154 | + descriptor.events = POLLOUT; |
| 155 | + descriptor.revents = 0; |
| 156 | + |
| 157 | + Int64 timeoutMilliseconds = ( timeout.asMicroseconds() + 999 ) / 1000; |
| 158 | + int pollTimeout = timeoutMilliseconds > std::numeric_limits<int>::max() |
| 159 | + ? std::numeric_limits<int>::max() |
| 160 | + : static_cast<int>( timeoutMilliseconds ); |
| 161 | + |
| 162 | + // Wait for something to write on our socket (which means that the connection request |
| 163 | + // has returned). poll() is not limited by FD_SETSIZE, unlike select(). |
| 164 | + if ( poll( &descriptor, 1, pollTimeout ) > 0 ) { |
| 165 | +#endif |
154 | 166 | // At this point the connection may have been either accepted or refused. |
155 | 167 | // To know whether it's a success or a failure, we must check the address of the |
156 | 168 | // connected peer |
|
0 commit comments