diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceSocket.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceSocket.cpp index 6d38c5d27c..507f0b2cca 100644 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceSocket.cpp +++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceSocket.cpp @@ -184,19 +184,24 @@ static void SocketStartAsyncRead(AsyncSocket sock) hsLockGuard(sock->fCritsect); uint8_t* start = sock->fBuffer + sock->fBytesLeft; size_t count = sizeof(sock->fBuffer) - sock->fBytesLeft; + hsAssert(sock->fSock.is_open(), "Read from a closed socket"); sock->fSock.async_read_some(asio::buffer(start, count), [sock](const asio::error_code& err, size_t bytes) { if (err) { bool isEOFError = (err.category() == asio::error::get_misc_category() && err.value() == asio::error::eof); bool isAbortedError = (err.category() == asio::error::get_system_category() && err.value() == asio::error::operation_aborted); if (isEOFError || isAbortedError) { - if (sock->fNotifyProc) { + FAsyncNotifySocketProc notifyProc = nullptr; + { + hsLockGuard(sock->fCritsect); + notifyProc = sock->fNotifyProc; + sock->fNotifyProc = nullptr; + } + if (notifyProc) { // We have to be extremely careful from this point because // sockets can be deleted during the notification callback. // After this call, the application becomes responsible for // calling AsyncSocketDelete at some later point in time. - FAsyncNotifySocketProc notifyProc = sock->fNotifyProc; - sock->fNotifyProc = nullptr; notifyProc((AsyncSocket)sock, kNotifySocketDisconnect, nullptr, &sock->fUserState); } } else { @@ -208,6 +213,7 @@ static void SocketStartAsyncRead(AsyncSocket sock) if (!bytes) return; + hsLockGuard(sock->fCritsect); sock->fBytesLeft += bytes; AsyncNotifySocketRead notifyRead; @@ -273,9 +279,11 @@ static bool SocketInitConnect(ConnectOperation& op) { // This steals ownership of op->fSock auto sock = std::make_unique(op); + hsLockGuard(sock->fCritsect); sock->initTimeMs = hsTimer::GetMilliSeconds(); + hsAssert(sock->fSock.is_open(), "Socket closed during connect?"); asio::error_code err; sock->fSock.non_blocking(true, err); if (err) @@ -341,6 +349,7 @@ void AsyncSocketConnect(AsyncCancelId* cancelId, const plNetAddress& netAddr, tcp::endpoint remoteAddr(asio::ip::address_v4(netAddr.GetHostBytes()), netAddr.GetPort()); op->fSock.async_connect(remoteAddr, [op](const asio::error_code& connError) { + hsLockGuard(s_connectCrit); // This operation is no longer a candidate for cleanup or cancellation // by the time we get a callback from async_connect bool success; @@ -360,10 +369,7 @@ void AsyncSocketConnect(AsyncCancelId* cancelId, const plNetAddress& netAddr, op->fNotifyProc(nullptr, kNotifySocketConnectFailed, &failed, nullptr); } - { - hsLockGuard(s_connectCrit); - s_connectList.erase(op); - } + s_connectList.erase(op); PerfSubCounter(kAsyncPerfSocketConnAttemptsOutCurr, 1); }); @@ -402,6 +408,7 @@ static void HardCloseSocket(AsyncSocket conn) void AsyncSocketDisconnect(AsyncSocket conn, bool hardClose) { + hsLockGuard(conn->fCritsect); if (!conn->fSock.is_open()) return; @@ -417,7 +424,7 @@ void AsyncSocketDisconnect(AsyncSocket conn, bool hardClose) static bool SocketQueueAsyncWrite(AsyncSocket conn, const void* data, size_t bytes) { - hsLockGuard(s_connectCrit); + hsLockGuard(conn->fCritsect); // check for data backlog if (!conn->fWriteOps.empty()) { @@ -478,8 +485,9 @@ static bool SocketQueueAsyncWrite(AsyncSocket conn, const void* data, size_t byt op->fNotify.bytesCommitted = op->fNotify.bytes; } } + hsAssert(conn->fSock.is_open(), "Write to a closed socket"); async_write(conn->fSock, allWrites, [conn](const asio::error_code& err, size_t bytes) { - hsLockGuard(s_connectCrit); + hsLockGuard(conn->fCritsect); while (bytes != 0) { hsAssert(conn->fWriteOps.size() > 0, "buffer mismatch"); WriteOperation* op = conn->fWriteOps.front(); @@ -508,6 +516,7 @@ bool AsyncSocketSend(AsyncSocket conn, const void* data, size_t bytes) // data right away, we do so in order to save extra allocations for the // write buffer. Otherwise, we must queue it for an async write below. if (conn->fWriteOps.empty()) { + hsAssert(conn->fSock.is_open(), "Write to a closed socket"); asio::error_code err; size_t bytesSent = conn->fSock.write_some(asio::buffer(data, bytes), err); if (!err) { diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp index 221b12a8a9..8f8f62bf75 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp @@ -1797,7 +1797,6 @@ bool RecvMsg(const uint8_t buffer[], unsigned bytes, void* p const Auth2Cli_KickedOff & msg = *(const Auth2Cli_KickedOff *)buffer; ReportNetError(kNetProtocolCli2Auth, msg.reason); - NetCliAuthDisconnect(); return true; }