From 30c05a2e1187d9bd851869a2b16a5436064c82e2 Mon Sep 17 00:00:00 2001 From: m910q Date: Fri, 26 Aug 2022 05:01:02 +0200 Subject: [PATCH] Added support for Socket.Select() under Linux --- BeefLibs/corlib/src/Net/Socket.bf | 87 +++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 17 deletions(-) diff --git a/BeefLibs/corlib/src/Net/Socket.bf b/BeefLibs/corlib/src/Net/Socket.bf index d62d9cff..25eba8dd 100644 --- a/BeefLibs/corlib/src/Net/Socket.bf +++ b/BeefLibs/corlib/src/Net/Socket.bf @@ -14,18 +14,6 @@ namespace System.Net public struct HSocket : uint { } -#else - public struct HSocket : uint32 - { - } -#endif - - [CRepr] - public struct TimeVal - { - public int32 mSec; - public int32 mUSec; - } [CRepr] public struct FDSet @@ -52,6 +40,54 @@ namespace System.Net } } +#else + public struct HSocket : uint32 + { + } + + [CRepr] + public struct FDSet + { + const uint BITS_PER_MASK = sizeof(uint) * 8; + const uint MASK_COUNT = 4096 / sizeof(uint); + const uint MAX_ALLOWED_FD = MASK_COUNT * BITS_PER_MASK; + + uint[MASK_COUNT] mSocketBitMasks; + uint32 afterLastBit; + + public bool Add(HSocket s) mut + { + let fd = (uint32)s; + + if (fd > MAX_ALLOWED_FD) + return false; + + if (fd >= afterLastBit) + afterLastBit = fd + 1; + + mSocketBitMasks[fd / BITS_PER_MASK] |= 1U << (fd & (BITS_PER_MASK - 1)); + return true; + } + + public bool IsSet(HSocket s) + { + let fd = (uint32)s; + if (fd > MAX_ALLOWED_FD) + return false; + return (mSocketBitMasks[fd / BITS_PER_MASK] & (1U << (fd & (BITS_PER_MASK - 1)))) != 0; + } + } +#endif + + [CRepr] + public struct TimeVal + { + public int32 mSec; + public int32 mUSec; + } + + + #if BF_PLATFORM_WINDOWS [CRepr] struct WSAData @@ -223,7 +259,7 @@ namespace System.Net #endif [CLink, CallingConvention(.Stdcall)] - static extern int32 select(int nfds, FDSet* readFDS, FDSet* writeFDS, FDSet* exceptFDS, TimeVal* timeVal); + static extern int32 select(int32 nfds, FDSet* readFDS, FDSet* writeFDS, FDSet* exceptFDS, TimeVal* timeVal); [CLink, CallingConvention(.Stdcall)] static extern int32 recv(HSocket s, void* ptr, int32 len, int32 flags); @@ -387,7 +423,8 @@ namespace System.Net TimeVal timeVal; timeVal.mSec = (.)(waitTimeMS / 1000); timeVal.mUSec = (.)((waitTimeMS % 1000) * 1000); - return select(0, readFDS, writeFDS, exceptFDS, &timeVal); + + return Select(readFDS, writeFDS, exceptFDS, &timeVal); } public static int32 Select(FDSet* readFDS, FDSet* writeFDS, FDSet* exceptFDS, float waitTimeMS) @@ -396,7 +433,24 @@ namespace System.Net TimeVal timeVal; timeVal.mSec = (.)(waitTimeUS / (1000*1000)); timeVal.mUSec = (.)(waitTimeUS % (1000*1000)); - return select(0, readFDS, writeFDS, exceptFDS, &timeVal); + + return Select(readFDS, writeFDS, exceptFDS, &timeVal); + } + + private static int32 Select(FDSet* readFDS, FDSet* writeFDS, FDSet* exceptFDS, TimeVal* timeVal) + { +#if BF_PLATFORM_WINDOWS + const int32 nfds = 0; // Ignored +#else + int32 nfds = 0; + if (readFDS != null) + nfds = (.)readFDS.[Friend]afterLastBit; + if (writeFDS != null) + nfds = Math.Max(nfds, (.)writeFDS.[Friend]afterLastBit); + if (exceptFDS != null) + nfds = Math.Max(nfds, (.)exceptFDS.[Friend]afterLastBit); +#endif + return select(nfds, readFDS, writeFDS, exceptFDS, timeVal); } public int32 DbgRecv(void* ptr, int32 size) @@ -466,5 +520,4 @@ namespace System.Net mHandle = INVALID_SOCKET; } } -} - +} \ No newline at end of file