mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Windows: Dynamically load WSAPoll method from Ws2_32.dll to restore compatibility with older Windows versions
This commit is contained in:
parent
978faaca83
commit
eb780b56b8
1 changed files with 76 additions and 50 deletions
|
|
@ -55,6 +55,24 @@ namespace juce
|
|||
//==============================================================================
|
||||
namespace SocketHelpers
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
using WSAPollFunc = int (WSAAPI*) (LPWSAPOLLFD, ULONG, INT);
|
||||
static WSAPollFunc wsaPollFunc = nullptr;
|
||||
|
||||
static void checkForWSAPoll()
|
||||
{
|
||||
static bool hasChecked = false;
|
||||
|
||||
if (! hasChecked)
|
||||
{
|
||||
hasChecked = true;
|
||||
|
||||
if (auto* moduleHandle = GetModuleHandleW (L"Ws2_32.dll"))
|
||||
wsaPollFunc = (WSAPollFunc) GetProcAddress (moduleHandle, "WSAPoll");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void initSockets()
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
|
|
@ -67,6 +85,8 @@ namespace SocketHelpers
|
|||
WSADATA wsaData;
|
||||
const WORD wVersionRequested = MAKEWORD (1, 1);
|
||||
WSAStartup (wVersionRequested, &wsaData);
|
||||
|
||||
checkForWSAPoll();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -286,9 +306,61 @@ namespace SocketHelpers
|
|||
if (! lock.isLocked())
|
||||
return -1;
|
||||
|
||||
auto hasErrorOccured = [&handle] () -> bool
|
||||
{
|
||||
auto h = handle.load();
|
||||
|
||||
if (h == invalidSocket)
|
||||
return true;
|
||||
|
||||
int opt;
|
||||
juce_socklen_t len = sizeof (opt);
|
||||
|
||||
if (getsockopt (h, SOL_SOCKET, SO_ERROR, (char*) &opt, &len) < 0 || opt != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
auto h = handle.load();
|
||||
|
||||
#if JUCE_MINGW
|
||||
#if ! JUCE_MINGW
|
||||
#if JUCE_WINDOWS
|
||||
if (wsaPollFunc != nullptr)
|
||||
#endif
|
||||
{
|
||||
short eventsFlag = (forReading ? POLLIN : POLLOUT);
|
||||
pollfd pfd { (SocketHandle) h, eventsFlag, 0 };
|
||||
|
||||
int result = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
result = SocketHelpers::wsaPollFunc (&pfd, 1, timeoutMsecs);
|
||||
#else
|
||||
result = poll (&pfd, 1, timeoutMsecs);
|
||||
#endif
|
||||
|
||||
if (result >= 0
|
||||
#if JUCE_WINDOWS
|
||||
|| result == SOCKET_ERROR
|
||||
#else
|
||||
|| errno != EINTR
|
||||
#endif
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result < 0 || hasErrorOccured())
|
||||
return -1;
|
||||
|
||||
return (pfd.revents & eventsFlag) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct timeval timeout;
|
||||
struct timeval* timeoutp;
|
||||
|
||||
|
|
@ -309,59 +381,13 @@ namespace SocketHelpers
|
|||
FD_ZERO (&wset);
|
||||
FD_SET (h, &wset);
|
||||
|
||||
fd_set* const prset = forReading ? &rset : nullptr;
|
||||
fd_set* const pwset = forReading ? nullptr : &wset;
|
||||
fd_set* prset = forReading ? &rset : nullptr;
|
||||
fd_set* pwset = forReading ? nullptr : &wset;
|
||||
|
||||
if (select ((int) h + 1, prset, pwset, 0, timeoutp) < 0)
|
||||
return -1;
|
||||
#else
|
||||
short eventsFlag = (forReading ? POLLIN : POLLOUT);
|
||||
pollfd pfd { (SocketHandle) h, eventsFlag, 0 };
|
||||
|
||||
int result = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
result = WSAPoll (&pfd, 1, timeoutMsecs);
|
||||
#else
|
||||
result = poll (&pfd, 1, timeoutMsecs);
|
||||
#endif
|
||||
|
||||
if (result >= 0
|
||||
#if JUCE_WINDOWS
|
||||
|| result == SOCKET_ERROR
|
||||
#else
|
||||
|| errno != EINTR
|
||||
#endif
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result < 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
// we are closing
|
||||
if (handle.load() < 0)
|
||||
if (select ((int) h + 1, prset, pwset, nullptr, timeoutp) < 0 || hasErrorOccured())
|
||||
return -1;
|
||||
|
||||
{
|
||||
int opt;
|
||||
juce_socklen_t len = sizeof (opt);
|
||||
|
||||
if (getsockopt (h, SOL_SOCKET, SO_ERROR, (char*) &opt, &len) < 0
|
||||
|| opt != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if JUCE_MINGW
|
||||
return FD_ISSET (h, forReading ? &rset : &wset) ? 1 : 0;
|
||||
#else
|
||||
return (pfd.revents & eventsFlag) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static addrinfo* getAddressInfo (bool isDatagram, const String& hostName, int portNumber)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue