From 1fb36548ea51950a0634b86b4a1c1d7c993a944f Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Sat, 19 Oct 2024 17:47:05 +0100 Subject: [PATCH] [*] Minor net fixes [*] Fix async shutdown / inline shutdown condition [*] Fix multiple net triggers [*] Fix spurious UDP Session Socket timeouts --- Source/IO/Net/AuNetSocket.NT.cpp | 2 +- Source/IO/Net/AuNetSocket.Unix.cpp | 2 +- Source/IO/Net/AuNetSocket.cpp | 3 ++ Source/IO/Net/AuNetSocketChannelOutput.cpp | 5 +++ Source/IO/Net/AuNetSocketChannelOutput.hpp | 1 + .../Net/AuNetSocketOverlappedOperation.NT.cpp | 31 +++++++++++++++++-- .../Net/AuNetSocketOverlappedOperation.NT.hpp | 3 ++ .../AuNetSocketOverlappedOperation.Unix.cpp | 27 +++++++++++++--- .../AuNetSocketOverlappedOperation.Unix.hpp | 2 ++ Source/IO/Net/AuNetSocketServer.NT.cpp | 1 + Source/IO/Net/AuSocketStats.cpp | 1 + .../AuNetDatagramSocketEviction.cpp | 5 +-- 12 files changed, 71 insertions(+), 12 deletions(-) diff --git a/Source/IO/Net/AuNetSocket.NT.cpp b/Source/IO/Net/AuNetSocket.NT.cpp index 66857a30..efdccb6b 100644 --- a/Source/IO/Net/AuNetSocket.NT.cpp +++ b/Source/IO/Net/AuNetSocket.NT.cpp @@ -314,7 +314,7 @@ namespace Aurora::IO::Net } else { - if (!this->socketChannel_.outputChannel.AsWritableByteBuffer()->RemainingBytes()) + if (this->socketChannel_.outputChannel.CanShutdown()) { this->Shutdown(true); } diff --git a/Source/IO/Net/AuNetSocket.Unix.cpp b/Source/IO/Net/AuNetSocket.Unix.cpp index 332f9d20..cbe1ebe1 100644 --- a/Source/IO/Net/AuNetSocket.Unix.cpp +++ b/Source/IO/Net/AuNetSocket.Unix.cpp @@ -282,7 +282,7 @@ namespace Aurora::IO::Net } else { - if (!this->socketChannel_.outputChannel.AsWritableByteBuffer()->RemainingBytes()) + if (this->socketChannel_.outputChannel.CanShutdown()) { this->Shutdown(true); } diff --git a/Source/IO/Net/AuNetSocket.cpp b/Source/IO/Net/AuNetSocket.cpp index 7626aa48..036b5e09 100644 --- a/Source/IO/Net/AuNetSocket.cpp +++ b/Source/IO/Net/AuNetSocket.cpp @@ -318,6 +318,8 @@ namespace Aurora::IO::Net return; } + this->connectOperation.ReleaseWatcher(); + auto pDriver = this->pSocketDriver_; if (bool(pDriver)) { @@ -635,6 +637,7 @@ namespace Aurora::IO::Net return; } + this->connectOperation.ReleaseWatcher(); this->socketChannel_.StopTime(); this->pWorker_->RemoveSocket(this); diff --git a/Source/IO/Net/AuNetSocketChannelOutput.cpp b/Source/IO/Net/AuNetSocketChannelOutput.cpp index 126abf0c..98481549 100644 --- a/Source/IO/Net/AuNetSocketChannelOutput.cpp +++ b/Source/IO/Net/AuNetSocketChannelOutput.cpp @@ -263,6 +263,11 @@ namespace Aurora::IO::Net return this->outputWriteQueue_.IsEmpty() && AuAtomicLoad(&this->uCompleteCounter_) == 0; } + bool SocketChannelOutput::CanShutdown() + { + return this->CanResize() && !this->AsWritableByteBuffer()->RemainingBytes(); + } + void SocketChannelOutput::OnAsyncFileOpFinished(AuUInt64 offset, AuUInt32 length) { AuAtomicSub(&this->outputBuffer_.uInUseCounter, 1u); diff --git a/Source/IO/Net/AuNetSocketChannelOutput.hpp b/Source/IO/Net/AuNetSocketChannelOutput.hpp index d6f88d33..9cb17a2d 100644 --- a/Source/IO/Net/AuNetSocketChannelOutput.hpp +++ b/Source/IO/Net/AuNetSocketChannelOutput.hpp @@ -37,6 +37,7 @@ namespace Aurora::IO::Net AuByteBuffer &GetByteBuffer(); bool CanResize(); + bool CanShutdown(); private: friend struct SocketBase; diff --git a/Source/IO/Net/AuNetSocketOverlappedOperation.NT.cpp b/Source/IO/Net/AuNetSocketOverlappedOperation.NT.cpp index 8f250e34..08944347 100644 --- a/Source/IO/Net/AuNetSocketOverlappedOperation.NT.cpp +++ b/Source/IO/Net/AuNetSocketOverlappedOperation.NT.cpp @@ -49,9 +49,24 @@ namespace Aurora::IO::Net if (dwErrorCode == ERROR_IO_PENDING) { this->pSocket = that; - SysAssert(pWorker->ToProcessor()->StartSimpleLSWatchEx(this->pEvent, - AuSPtr(that, this), - true)); + + if (auto pOld = AuTryLockMemoryType(this->wpThat)) + { + return true; + } + else + { + auto pThat = pWorker->ToProcessor()->StartSimpleLSWatchEx(this->pEvent, + AuSPtr(that, this), + !this->bMultipleTrigger); + if (!pThat) + { + return false; + } + + this->wpThat = pThat; + return true; + } return true; } else @@ -64,6 +79,16 @@ namespace Aurora::IO::Net } } + void SocketOverlappedOperation::ReleaseWatcher() + { + if (auto pOld = AuTryLockMemoryType(this->wpThat)) + { + pOld->StopWatch(); + } + + AuResetMember(this->wpThat); + } + bool SocketOverlappedOperation::IsValid() { return bool(this->pEvent); diff --git a/Source/IO/Net/AuNetSocketOverlappedOperation.NT.hpp b/Source/IO/Net/AuNetSocketOverlappedOperation.NT.hpp index 77beb496..f41b9ab0 100644 --- a/Source/IO/Net/AuNetSocketOverlappedOperation.NT.hpp +++ b/Source/IO/Net/AuNetSocketOverlappedOperation.NT.hpp @@ -49,7 +49,10 @@ namespace Aurora::IO::Net bool IsValid(); + void ReleaseWatcher(); + private: bool bHasFlipped {}; + AuWPtr wpThat; }; } \ No newline at end of file diff --git a/Source/IO/Net/AuNetSocketOverlappedOperation.Unix.cpp b/Source/IO/Net/AuNetSocketOverlappedOperation.Unix.cpp index a9766a19..d65d0fd8 100644 --- a/Source/IO/Net/AuNetSocketOverlappedOperation.Unix.cpp +++ b/Source/IO/Net/AuNetSocketOverlappedOperation.Unix.cpp @@ -68,24 +68,41 @@ namespace Aurora::IO::Net bool SocketOverlappedOperation::BeginOperation(const AuSPtr &that, const AuSPtr &pWorker) { - this->pSocket = that; if (!this->pEvent) { return false; } + + this->pSocket = that; - auto bStatus = pWorker->ToProcessor()->StartSimpleLSWatchEx(this->pEvent, - AuSPtr(that, this), - true); - if (!bStatus) + if (auto pOld = AuTryLockMemoryType(this->wpThat)) + { + return true; + } + + auto pThat = pWorker->ToProcessor()->StartSimpleLSWatchEx(this->pEvent, + AuSPtr(that, this), + !this->bMultipleTrigger); + if (!pThat) { this->pSocket.reset(); return false; } + this->wpThat = pThat; return true; } + void SocketOverlappedOperation::ReleaseWatcher() + { + if (auto pOld = AuTryLockMemoryType(this->wpThat)) + { + pOld->StopWatch(); + } + + AuResetMember(this->wpThat); + } + void SocketOverlappedOperation::UpdateTrigger(const AuSPtr &pTrigger) { this->pEvent = pTrigger; diff --git a/Source/IO/Net/AuNetSocketOverlappedOperation.Unix.hpp b/Source/IO/Net/AuNetSocketOverlappedOperation.Unix.hpp index 71711cb8..3e7d0b8e 100644 --- a/Source/IO/Net/AuNetSocketOverlappedOperation.Unix.hpp +++ b/Source/IO/Net/AuNetSocketOverlappedOperation.Unix.hpp @@ -53,8 +53,10 @@ namespace Aurora::IO::Net bool IsValid(); + void ReleaseWatcher(); private: bool bHasFlipped {}; + AuWPtr wpThat; }; } \ No newline at end of file diff --git a/Source/IO/Net/AuNetSocketServer.NT.cpp b/Source/IO/Net/AuNetSocketServer.NT.cpp index 4e5bbef1..5a13314a 100644 --- a/Source/IO/Net/AuNetSocketServer.NT.cpp +++ b/Source/IO/Net/AuNetSocketServer.NT.cpp @@ -136,5 +136,6 @@ namespace Aurora::IO::Net void SocketServerImpl::DetroyServer() { + this->acceptOperation_.ReleaseWatcher(); } } \ No newline at end of file diff --git a/Source/IO/Net/AuSocketStats.cpp b/Source/IO/Net/AuSocketStats.cpp index f2d719ef..5f2edbf4 100644 --- a/Source/IO/Net/AuSocketStats.cpp +++ b/Source/IO/Net/AuSocketStats.cpp @@ -14,6 +14,7 @@ namespace Aurora::IO::Net { this->Start(); this->calculator.AddData(uBytes); + this->uLastTimeSteadyMS = AuTime::SteadyClockMS(); } AuInt64 SocketStats::GetFirstTickTimeMS() diff --git a/Source/IO/Net/SocketOverDatagram/AuNetDatagramSocketEviction.cpp b/Source/IO/Net/SocketOverDatagram/AuNetDatagramSocketEviction.cpp index 2b9617cc..15137566 100644 --- a/Source/IO/Net/SocketOverDatagram/AuNetDatagramSocketEviction.cpp +++ b/Source/IO/Net/SocketOverDatagram/AuNetDatagramSocketEviction.cpp @@ -32,8 +32,9 @@ namespace Aurora::IO::Net { auto uLastRecv = pSession->channel.GetRecvStatsEx().uLastTimeSteadyMS; auto uLastSend = pSession->channel.GetSendStatsEx().uLastTimeSteadyMS; - if ((uSocketTimeoutRecvMS && (uLastRecv + uSocketTimeoutRecvMS < uNow)) || - (uSocketTimeoutAnyMS && ((uLastRecv + uSocketTimeoutAnyMS < uNow) || (uLastSend + uSocketTimeoutAnyMS < uNow)))) + if ((uSocketTimeoutRecvMS && (uLastRecv && (uLastRecv + uSocketTimeoutRecvMS < uNow))) || + (uSocketTimeoutAnyMS && ((uLastRecv && (uLastRecv + uSocketTimeoutAnyMS < uNow)) || + (uLastSend && (uLastSend + uSocketTimeoutAnyMS < uNow))))) { abortions[pSession->pWorker].push_back(pSession); }