From c084f18c62443872c4395400045eff430336d1f8 Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Thu, 27 Jul 2023 19:39:43 +0100 Subject: [PATCH] [*] Resolve one stated Windows 7 defect --- Media/Windows 7 Defects.txt | 4 +- Source/IO/Net/AuNetResolver.NT.cpp | 140 +++++++++++++++++++++-------- Source/IO/Net/AuNetResolver.NT.hpp | 1 + 3 files changed, 106 insertions(+), 39 deletions(-) diff --git a/Media/Windows 7 Defects.txt b/Media/Windows 7 Defects.txt index e1f2d5ae..fb84fd42 100644 --- a/Media/Windows 7 Defects.txt +++ b/Media/Windows 7 Defects.txt @@ -2,6 +2,4 @@ 2 - soft defect; emuation performance) The time to wake metric across AuThreading::[Wake/Wait]OnAddress starts off at 1.5 - 2.2x modern Windows with RtlWaitOnAddress; although, the best case of basic primitives will still be faster than SRW Locks of Windows 7 through 11. Era correct internal NT apis are used across XP - Windows 11 targets. Note, WaitOnAddress emulation is not required for basic thread primitives; such scheduler indirection would only hurt performance. Performance should otherwise be exactly what you would expect once you remove Microsofts regressing CRT and lackluster stock thread primitives from the equation. -3) DNS look ups, when using the systems interface, will block the users thread as opposed to being an overlapped operation. Most application vendors would want to run their IO, especially network io, on a seperate thread from UI. This shouldn't be much of an issue for Windows 7 clients, I suppose. - -4 - soft defect; workaround available) Stock Windows 7 console host is infamously bad. ConsoleTTY can in theory continue to work down to targets as old as Windows XP without the use of third party software; however, it should be noted TrueType fonts tend to cause hideous positioning faults when used with Aurora::Console::ConsoleTTY::GetTTYConsole()->Start(). Raster fonts tend to have better compatibility on older Windows operating systems. Aurora::Console::ConsoleTTY::* and Aurora::Console::ConsoleSTD::* (noncanonical apis) remain available and fully functional under Windows 7. \ No newline at end of file +3 - soft defect; workaround available) Stock Windows 7 console host is infamously bad. ConsoleTTY can in theory continue to work down to targets as old as Windows XP without the use of third party software; however, it should be noted TrueType fonts tend to cause hideous positioning faults when used with Aurora::Console::ConsoleTTY::GetTTYConsole()->Start(). Raster fonts tend to have better compatibility on older Windows operating systems. Aurora::Console::ConsoleTTY::* and Aurora::Console::ConsoleSTD::* (noncanonical apis) remain available and fully functional under Windows 7. \ No newline at end of file diff --git a/Source/IO/Net/AuNetResolver.NT.cpp b/Source/IO/Net/AuNetResolver.NT.cpp index 7556daf9..b3e25b7c 100644 --- a/Source/IO/Net/AuNetResolver.NT.cpp +++ b/Source/IO/Net/AuNetResolver.NT.cpp @@ -34,6 +34,11 @@ namespace Aurora::IO::Net ADDRINFOEXW infoEx {}; int iInfoEx { 0 }; + if (!this->pEvent) + { + return false; + } + if (this->bA && this->bAAAA) { infoEx.ai_family = AF_UNSPEC; @@ -73,59 +78,114 @@ namespace Aurora::IO::Net } else { - iRet = pGetAddrInfoExW(AuLocale::ConvertFromUTF8(this->hostname).data(), - nullptr, - NS_DNS, - nullptr, - &infoEx, - &this->resultHandle_, - nullptr, - nullptr, - nullptr, - nullptr); + auto pShared = this->SharedFromThis(); + + auto pThread = AuThreads::ThreadUnique(AuThreads::ThreadInfo( + AuMakeShared(AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind([=]() + { + int iRet {}; + if ((iRet = pGetAddrInfoExW(AuLocale::ConvertFromUTF8(pShared->hostname).data(), + nullptr, + NS_DNS, + nullptr, + &infoEx, + &pShared->resultHandle_, + nullptr, + nullptr, + nullptr, + nullptr)) != ERROR_SUCCESS) + { + pShared->bForceError_ = true; + pShared->uOsError = iRet; + pShared->error_ = pShared->ToError(); + } + + pShared->pEvent->Set(); + })), + AuThreads::IThreadVectorsFunctional::OnExit_t{}), + "Legacy Win32 DNS Request" + )); + + if (!pThread) + { + return false; + } + + pThread->Run(); + pThread->Detach(); + + iRet = ERROR_IO_PENDING; } } else if (pgetaddrinfo) { - ADDRINFOA infoA { 0 }; - PADDRINFOA pInfoRet {}; - infoA.ai_family = infoEx.ai_family; + auto pShared = this->SharedFromThis(); - iRet = pgetaddrinfo(this->hostname.c_str(), - nullptr, - &infoA, - &pInfoRet); - - if (iRet == 0) - { - auto pCurrent = pInfoRet; - - while (pCurrent) + auto pThread = AuThreads::ThreadUnique(AuThreads::ThreadInfo( + AuMakeShared(AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind([=]() { - NetEndpoint endpoint; - AuMemcpy(endpoint.hint, pCurrent->ai_addr, pCurrent->ai_addrlen); - DeoptimizeEndpoint(endpoint); + int iRet {}; + ADDRINFOA infoA { 0 }; + PADDRINFOA pInfoRet {}; + infoA.ai_family = infoEx.ai_family; - if (!AuTryInsert(this->processedIps_, endpoint.ip)) + iRet = pgetaddrinfo(pShared->hostname.c_str(), + nullptr, + &infoA, + &pInfoRet); + + if (iRet == 0) { - return false; + auto pCurrent = pInfoRet; + + while (pCurrent) + { + NetEndpoint endpoint; + AuMemcpy(endpoint.hint, pCurrent->ai_addr, pCurrent->ai_addrlen); + DeoptimizeEndpoint(endpoint); + + if (!AuTryInsert(pShared->processedIps_, endpoint.ip)) + { + pShared->bForceError_ = true; + break; + } + + pCurrent = pCurrent->ai_next; + } + } + else + { + pShared->bForceError_ = true; + pShared->uOsError = iRet; + pShared->error_ = pShared->ToError(); } - pCurrent = pCurrent->ai_next; - } + if (pInfoRet && pfreeaddrinfo) + { + pfreeaddrinfo(pInfoRet); + } + + pShared->pEvent->Set(); + })), + AuThreads::IThreadVectorsFunctional::OnExit_t{}), + "Legacy Win32 DNS Request" + )); + + if (!pThread) + { + return false; } - if (pInfoRet && pfreeaddrinfo) - { - pfreeaddrinfo(pInfoRet); - } + pThread->Run(); + pThread->Detach(); + + iRet = ERROR_IO_PENDING; } else { return false; } - this->hName_ = hHandle; return this->FinishOperationEx(AuSharedFromThis(), this->pWorker_, @@ -165,7 +225,10 @@ namespace Aurora::IO::Net { try { - this->error_ = ENetworkError::eAsyncError; + if (this->error_.netError == ENetworkError::eEnumInvalid) + { + this->error_ = ENetworkError::eAsyncError; + } this->pCompletion_->OnFailure((void *)&this->error_); } catch (...) @@ -224,6 +287,11 @@ namespace Aurora::IO::Net { auto pCurrent = this->resultHandle_; + if (this->bForceError_) + { + return false; + } + while (pCurrent) { NetEndpoint endpoint; diff --git a/Source/IO/Net/AuNetResolver.NT.hpp b/Source/IO/Net/AuNetResolver.NT.hpp index 9d344b0d..31dc5a91 100644 --- a/Source/IO/Net/AuNetResolver.NT.hpp +++ b/Source/IO/Net/AuNetResolver.NT.hpp @@ -46,6 +46,7 @@ namespace Aurora::IO::Net AuList processedIps_; AuSPtr, NetError>> pCompletion_; bool bHasCompleted_ {}; + bool bForceError_ {}; PADDRINFOEXW resultHandle_ {}; NetError error_; HANDLE hName_ { NULL };