From 6193fd90ae0ef8f5ec8f0c65433248a2d19af9ba Mon Sep 17 00:00:00 2001 From: dgelessus Date: Sun, 20 Aug 2023 02:40:04 +0200 Subject: [PATCH 1/6] Remove unused and unimplemented NetCliQueue --- .../Plasma/NucleusLib/pnNetCli/pnNcCli.cpp | 24 +------------- Sources/Plasma/NucleusLib/pnNetCli/pnNetCli.h | 31 +------------------ 2 files changed, 2 insertions(+), 53 deletions(-) diff --git a/Sources/Plasma/NucleusLib/pnNetCli/pnNcCli.cpp b/Sources/Plasma/NucleusLib/pnNetCli/pnNcCli.cpp index a899ef00c3..119f599a41 100644 --- a/Sources/Plasma/NucleusLib/pnNetCli/pnNcCli.cpp +++ b/Sources/Plasma/NucleusLib/pnNetCli/pnNcCli.cpp @@ -122,10 +122,6 @@ struct NetCli { NetMsgChannel * channel; bool server; - // message queue - LINK(NetCli) link; - NetCliQueue * queue; - // message send/recv const NetMsgInitRecv * recvMsg; const NetMsgField * recvField; @@ -147,7 +143,7 @@ struct NetCli { std::vector recvBuffer; NetCli() - : sock(), protocol(), channel(), server(), queue(), recvMsg() + : sock(), protocol(), channel(), server(), recvMsg() , recvField(), recvFieldBytes(), recvDispatch(), sendCurr(), mode() , encryptFcn(), seed(), cryptIn(), cryptOut(), encryptParam() , sendBuffer() @@ -155,12 +151,6 @@ struct NetCli { } }; -struct NetCliQueue { - LISTDECL(NetCli, link) list; - unsigned lastSendMs; - unsigned flushTimeMs; -}; - namespace pnNetCli { @@ -419,10 +409,6 @@ static void BufferedSendData ( DEFAULT_FATAL(cmd->type); } } - - // prepare to flush this connection - if (cli->queue) - cli->queue->list.Link(cli); } //=========================================================================== @@ -1027,14 +1013,6 @@ void NetCliClearSocket (NetCli * cli) { cli->sock = nullptr; } -//============================================================================ -void NetCliSetQueue ( - NetCli * cli, - NetCliQueue * queue -) { - cli->queue = queue; -} - //============================================================================ void NetCliDisconnect ( NetCli * cli, diff --git a/Sources/Plasma/NucleusLib/pnNetCli/pnNetCli.h b/Sources/Plasma/NucleusLib/pnNetCli/pnNetCli.h index bc4ccb409f..a89ecfede1 100644 --- a/Sources/Plasma/NucleusLib/pnNetCli/pnNetCli.h +++ b/Sources/Plasma/NucleusLib/pnNetCli/pnNetCli.h @@ -262,9 +262,8 @@ struct NetMsg { unsigned count; }; -// Opaque types +// Opaque type struct NetCli; -struct NetCliQueue; /***************************************************************************** @@ -337,29 +336,6 @@ void NetMsgProtocolDestroy ( ); -/***************************************************************************** -* -* NetCliQueue -* -***/ - -NetCliQueue * NetCliQueueCreate ( - unsigned flushTimeMs -); - -void NetCliQueueDestroy ( - NetCliQueue * queue -); - -void NetCliQueueFlush ( - NetCliQueue * queue -); - -float NetCliQueueQueryFlush ( - NetCliQueue * queue -); - - /***************************************************************************** * * NetCli @@ -385,11 +361,6 @@ void NetCliClearSocket ( NetCli * cli ); -void NetCliSetQueue ( - NetCli * cli, - NetCliQueue * queue -); - void NetCliDisconnect ( NetCli * cli, bool hardClose From 5b2cc2e81c1e08ec219f4f2ea05a71cba9617025 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Sun, 20 Aug 2023 16:52:13 +0200 Subject: [PATCH 2/6] Replace s_conns lists with single pointers The code in the Connect functions already ensured that the lists never contain multiple connections, so there's no need to use lists at all. --- .../plNetGameLib/Private/plNglAuth.cpp | 43 +++++++++++-------- .../plNetGameLib/Private/plNglFile.cpp | 43 +++++++++++-------- .../plNetGameLib/Private/plNglGame.cpp | 35 +++++++++------ .../plNetGameLib/Private/plNglGateKeeper.cpp | 43 +++++++++++-------- 4 files changed, 99 insertions(+), 65 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp index 251badda09..bbab8994cb 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp @@ -88,7 +88,6 @@ struct CliAuConn : hsRefCnt { void Send (const uintptr_t fields[], unsigned count); std::recursive_mutex critsect; - LINK(CliAuConn) link; AsyncSocket sock; NetCli * cli; ST::string name; @@ -1249,7 +1248,7 @@ enum { static bool s_running; static std::recursive_mutex s_critsect; -static LISTDECL(CliAuConn, link) s_conns; +static CliAuConn* s_conn = nullptr; static CliAuConn * s_active; static ST::string s_accountName; static ShaDigest s_accountNamePassHash; @@ -1327,8 +1326,7 @@ static CliAuConn * GetConnIncRef (const char tag[]) { } //============================================================================ -static void UnlinkAndAbandonConn_CS (CliAuConn * conn) { - s_conns.Unlink(conn); +static void AbandonConn(CliAuConn* conn) { conn->abandoned = true; conn->StopAutoReconnect(); @@ -1425,7 +1423,9 @@ static void NotifyConnSocketConnectFailed (CliAuConn * conn) { { hsLockGuard(s_critsect); conn->cancelId = nullptr; - s_conns.Unlink(conn); + if (s_conn == conn) { + s_conn = nullptr; + } if (conn == s_active) s_active = nullptr; @@ -1444,7 +1444,9 @@ static void NotifyConnSocketDisconnect (CliAuConn * conn) { { hsLockGuard(s_critsect); conn->cancelId = nullptr; - s_conns.Unlink(conn); + if (s_conn == conn) { + s_conn = nullptr; + } if (conn == s_active) s_active = nullptr; @@ -1525,13 +1527,13 @@ static void Connect ( { hsLockGuard(s_critsect); - while (CliAuConn * oldConn = s_conns.Head()) { - if (oldConn != conn) - UnlinkAndAbandonConn_CS(oldConn); - else - s_conns.Unlink(oldConn); + if (CliAuConn* oldConn = s_conn) { + s_conn = nullptr; + if (oldConn != conn) { + AbandonConn(oldConn); + } } - s_conns.Link(conn); + s_conn = conn; } Cli2Auth_Connect connect; @@ -1643,7 +1645,10 @@ void CliAuConn::TimerReconnect () { if (!s_running) { hsLockGuard(s_critsect); - UnlinkAndAbandonConn_CS(this); + if (s_conn == this) { + s_conn = nullptr; + } + AbandonConn(this); } else { Ref("Connecting"); @@ -4671,8 +4676,10 @@ void AuthDestroy (bool wait) { { hsLockGuard(s_critsect); - while (CliAuConn * conn = s_conns.Head()) - UnlinkAndAbandonConn_CS(conn); + if (CliAuConn* conn = s_conn) { + s_conn = nullptr; + AbandonConn(conn); + } s_active = nullptr; } @@ -4769,8 +4776,10 @@ void NetCliAuthAutoReconnectEnable (bool enable) { void NetCliAuthDisconnect () { hsLockGuard(s_critsect); - while (CliAuConn * conn = s_conns.Head()) - UnlinkAndAbandonConn_CS(conn); + if (CliAuConn* conn = s_conn) { + s_conn = nullptr; + AbandonConn(conn); + } s_active = nullptr; } diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp index bedeabd6dc..dff93c44a2 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp @@ -69,7 +69,6 @@ namespace Ngl { namespace File { ***/ struct CliFileConn : hsRefCnt { - LINK(CliFileConn) link; hsReaderWriterLock sockLock; // to protect the socket pointer so we don't nuke it while using it AsyncSocket sock; ST::string name; @@ -234,7 +233,7 @@ enum { static bool s_running; static std::recursive_mutex s_critsect; -static LISTDECL(CliFileConn, link) s_conns; +static CliFileConn* s_conn = nullptr; static CliFileConn * s_active; static std::atomic s_perf[kNumPerf]; static unsigned s_connectBuildId; @@ -275,8 +274,7 @@ static CliFileConn * GetConnIncRef (const char tag[]) { } //============================================================================ -static void UnlinkAndAbandonConn_CS (CliFileConn * conn) { - s_conns.Unlink(conn); +static void AbandonConn(CliFileConn* conn) { conn->abandoned = true; if (conn->AutoReconnectEnabled()) @@ -325,7 +323,9 @@ static void NotifyConnSocketConnectFailed (CliFileConn * conn) { { hsLockGuard(s_critsect); conn->cancelId = nullptr; - s_conns.Unlink(conn); + if (s_conn == conn) { + s_conn = nullptr; + } if (conn == s_active) s_active = nullptr; @@ -355,7 +355,9 @@ static void NotifyConnSocketDisconnect (CliFileConn * conn) { { hsLockGuard(s_critsect); conn->cancelId = nullptr; - s_conns.Unlink(conn); + if (s_conn == conn) { + s_conn = nullptr; + } if (conn == s_active) s_active = nullptr; @@ -493,13 +495,13 @@ static void Connect (CliFileConn * conn) { { hsLockGuard(s_critsect); - while (CliFileConn * oldConn = s_conns.Head()) { - if (oldConn != conn) - UnlinkAndAbandonConn_CS(oldConn); - else - s_conns.Unlink(oldConn); + if (CliFileConn* oldConn = s_conn) { + s_conn = nullptr; + if (oldConn != conn) { + AbandonConn(oldConn); + } } - s_conns.Link(conn); + s_conn = conn; } Cli2File_Connect connect; @@ -587,7 +589,10 @@ void CliFileConn::TimerReconnect () { if (!s_running) { hsLockGuard(s_critsect); - UnlinkAndAbandonConn_CS(this); + if (s_conn == this) { + s_conn = nullptr; + AbandonConn(this); + } } else { Ref("Connecting"); @@ -1303,8 +1308,10 @@ void FileDestroy (bool wait) { { hsLockGuard(s_critsect); - while (CliFileConn * conn = s_conns.Head()) - UnlinkAndAbandonConn_CS(conn); + if (CliFileConn* conn = s_conn) { + s_conn = nullptr; + AbandonConn(conn); + } s_active = nullptr; } @@ -1379,8 +1386,10 @@ bool NetCliFileQueryConnected () { //============================================================================ void NetCliFileDisconnect () { hsLockGuard(s_critsect); - while (CliFileConn * conn = s_conns.Head()) - UnlinkAndAbandonConn_CS(conn); + if (CliFileConn* conn = s_conn) { + s_conn = nullptr; + AbandonConn(conn); + } s_active = nullptr; } diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp index 8b6d709394..e3a6e8c69f 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp @@ -55,8 +55,6 @@ namespace Ngl { namespace Game { ***/ struct CliGmConn : hsRefCnt { - LINK(CliGmConn) link; - std::recursive_mutex critsect; AsyncSocket sock; AsyncCancelId cancelId; @@ -157,7 +155,7 @@ enum { static bool s_running; static std::recursive_mutex s_critsect; -static LISTDECL(CliGmConn, link) s_conns; +static CliGmConn* s_conn = nullptr; static CliGmConn * s_active; static FNetCliGameRecvBufferHandler s_bufHandler; static FNetCliGameRecvGameMgrMsgHandler s_gameMgrMsgHandler; @@ -194,8 +192,7 @@ static CliGmConn * GetConnIncRef (const char tag[]) { } //============================================================================ -static void UnlinkAndAbandonConn_CS (CliGmConn * conn) { - s_conns.Unlink(conn); +static void AbandonConn(CliGmConn* conn) { conn->abandoned = true; if (conn->cancelId) { AsyncSocketConnectCancel(conn->cancelId); @@ -244,7 +241,9 @@ static void NotifyConnSocketConnectFailed (CliGmConn * conn) { { hsLockGuard(s_critsect); conn->cancelId = nullptr; - s_conns.Unlink(conn); + if (s_conn == conn) { + s_conn = nullptr; + } notify = s_running @@ -270,7 +269,9 @@ static void NotifyConnSocketDisconnect (CliGmConn * conn) { bool notify; { hsLockGuard(s_critsect); - s_conns.Unlink(conn); + if (s_conn == conn) { + s_conn = nullptr; + } notify = s_running @@ -377,9 +378,11 @@ static void Connect ( { hsLockGuard(s_critsect); - while (CliGmConn * conn = s_conns.Head()) - UnlinkAndAbandonConn_CS(conn); - s_conns.Link(conn); + if (CliGmConn* oldConn = s_conn) { + s_conn = nullptr; + AbandonConn(oldConn); + } + s_conn = conn; } Cli2Game_Connect connect; @@ -722,8 +725,10 @@ void GameDestroy (bool wait) { { hsLockGuard(s_critsect); - while (CliGmConn * conn = s_conns.Head()) - UnlinkAndAbandonConn_CS(conn); + if (CliGmConn* conn = s_conn) { + s_conn = nullptr; + AbandonConn(conn); + } s_active = nullptr; } @@ -783,8 +788,10 @@ void NetCliGameStartConnect ( //============================================================================ void NetCliGameDisconnect () { hsLockGuard(s_critsect); - while (CliGmConn * conn = s_conns.Head()) - UnlinkAndAbandonConn_CS(conn); + if (CliGmConn* conn = s_conn) { + s_conn = nullptr; + AbandonConn(conn); + } s_active = nullptr; } diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp index 9485306cf9..642ad50954 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp @@ -85,7 +85,6 @@ struct CliGkConn : hsRefCnt { void Send (const uintptr_t fields[], unsigned count); std::recursive_mutex critsect; - LINK(CliGkConn) link; AsyncSocket sock; NetCli * cli; ST::string name; @@ -184,7 +183,7 @@ enum { static bool s_running; static std::recursive_mutex s_critsect; -static LISTDECL(CliGkConn, link) s_conns; +static CliGkConn* s_conn = nullptr; static CliGkConn * s_active; static std::atomic s_perf[kNumPerf]; @@ -220,8 +219,7 @@ static CliGkConn * GetConnIncRef (const char tag[]) { } //============================================================================ -static void UnlinkAndAbandonConn_CS (CliGkConn * conn) { - s_conns.Unlink(conn); +static void AbandonConn(CliGkConn* conn) { conn->abandoned = true; conn->StopAutoReconnect(); @@ -312,7 +310,9 @@ static void NotifyConnSocketConnectFailed (CliGkConn * conn) { { hsLockGuard(s_critsect); conn->cancelId = nullptr; - s_conns.Unlink(conn); + if (s_conn == conn) { + s_conn = nullptr; + } if (conn == s_active) s_active = nullptr; @@ -331,7 +331,9 @@ static void NotifyConnSocketDisconnect (CliGkConn * conn) { { hsLockGuard(s_critsect); conn->cancelId = nullptr; - s_conns.Unlink(conn); + if (s_conn == conn) { + s_conn = nullptr; + } if (conn == s_active) s_active = nullptr; @@ -412,13 +414,13 @@ static void Connect ( { hsLockGuard(s_critsect); - while (CliGkConn * oldConn = s_conns.Head()) { - if (oldConn != conn) - UnlinkAndAbandonConn_CS(oldConn); - else - s_conns.Unlink(oldConn); + if (CliGkConn* oldConn = s_conn) { + s_conn = nullptr; + if (oldConn != conn) { + AbandonConn(oldConn); + } } - s_conns.Link(conn); + s_conn = conn; } Cli2GateKeeper_Connect connect; @@ -523,7 +525,10 @@ void CliGkConn::TimerReconnect () { if (!s_running) { hsLockGuard(s_critsect); - UnlinkAndAbandonConn_CS(this); + if (s_conn == this) { + s_conn = nullptr; + } + AbandonConn(this); } else { Ref("Connecting"); @@ -926,8 +931,10 @@ void GateKeeperDestroy (bool wait) { { hsLockGuard(s_critsect); - while (CliGkConn * conn = s_conns.Head()) - UnlinkAndAbandonConn_CS(conn); + if (CliGkConn* conn = s_conn) { + s_conn = nullptr; + AbandonConn(conn); + } s_active = nullptr; } @@ -994,8 +1001,10 @@ void NetCliGateKeeperStartConnect ( //============================================================================ void NetCliGateKeeperDisconnect () { hsLockGuard(s_critsect); - while (CliGkConn * conn = s_conns.Head()) - UnlinkAndAbandonConn_CS(conn); + if (CliGkConn* conn = s_conn) { + s_conn = nullptr; + AbandonConn(conn); + } s_active = nullptr; } From caee7c645a0d6b3c68d7810bd66a1ea8797d5572 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Sun, 20 Aug 2023 21:03:06 +0200 Subject: [PATCH 3/6] Convert plNglTrans lists from pnUtList to std::list --- .../Plasma/PubUtilLib/plNetGameLib/Intern.h | 1 - .../plNetGameLib/Private/plNglTrans.cpp | 64 +++++++++++-------- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h b/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h index 9074b8794b..3055f61cc0 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h @@ -290,7 +290,6 @@ enum ENetTransState { }; struct NetTrans : hsRefCnt { - LINK(NetTrans) m_link; ENetTransState m_state; ENetError m_result; unsigned m_transId; diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp index 9dbc38e8c9..f92bc1df2d 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp @@ -47,6 +47,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "../Pch.h" +#include namespace Ngl { /***************************************************************************** @@ -64,7 +65,7 @@ static const unsigned kDefaultTimeoutMs = 5 * 60 * 1000; static bool s_running; static std::recursive_mutex s_critsect; -static LISTDECL(NetTrans, m_link) s_transactions; +static std::list s_transactions; static std::atomic s_perf[kNumPerf]; static unsigned s_timeoutMs = kDefaultTimeoutMs; @@ -78,11 +79,12 @@ static unsigned s_timeoutMs = kDefaultTimeoutMs; //============================================================================ static NetTrans * FindTransIncRef_CS (unsigned transId, const char tag[]) { // There shouldn't be more than a few transactions; just do a linear scan - for (NetTrans * trans = s_transactions.Head(); trans; trans = s_transactions.Next(trans)) + for (NetTrans* trans : s_transactions) { if (trans->m_transId == transId) { trans->Ref(tag); return trans; } + } return nullptr; } @@ -128,7 +130,15 @@ NetTrans::NetTrans (ENetProtocol protocol, ETransType transType) //============================================================================ NetTrans::~NetTrans () { - ASSERT(!m_link.IsLinked()); +#if defined(HS_DEBUGGING) + { + hsLockGuard(s_critsect); + hsAssert( + std::find(s_transactions.begin(), s_transactions.end(), this) == s_transactions.end(), + "Destroying a transaction that's still in progress!" + ); + } +#endif --s_perfTransCount[m_transType]; --s_perf[kPerfCurrTransactions]; // DebugMsg("%s@%p destroyed", s_transTypes[m_transType], this); @@ -193,7 +203,7 @@ void NetTransSend (NetTrans * trans) { static unsigned s_transId; while (!trans->m_transId) trans->m_transId = ++s_transId; - s_transactions.Link(trans, kListTail); + s_transactions.push_back(trans); if (!s_running) CancelTrans_CS(trans, kNetErrRemoteShutdown); } @@ -220,8 +230,7 @@ bool NetTransRecv (unsigned transId, const uint8_t msg[], unsigned bytes) { //============================================================================ void NetTransCancel (unsigned transId, ENetError error) { hsLockGuard(s_critsect); - NetTrans * trans = s_transactions.Head(); - for (; trans; trans = trans->m_link.Next()) { + for (NetTrans* trans : s_transactions) { if (trans->m_transId == transId) { CancelTrans_CS(trans, error); break; @@ -232,8 +241,7 @@ void NetTransCancel (unsigned transId, ENetError error) { //============================================================================ void NetTransCancelByProtocol (ENetProtocol protocol, ENetError error) { hsLockGuard(s_critsect); - NetTrans * trans = s_transactions.Head(); - for (; trans; trans = trans->m_link.Next()) { + for (NetTrans* trans : s_transactions) { if (trans->m_protocol == protocol) CancelTrans_CS(trans, error); } @@ -242,8 +250,7 @@ void NetTransCancelByProtocol (ENetProtocol protocol, ENetError error) { //============================================================================ void NetTransCancelByConnId (unsigned connId, ENetError error) { hsLockGuard(s_critsect); - NetTrans * trans = s_transactions.Head(); - for (; trans; trans = trans->m_link.Next()) { + for (NetTrans* trans : s_transactions) { if (trans->m_connId == connId) CancelTrans_CS(trans, error); } @@ -252,31 +259,36 @@ void NetTransCancelByConnId (unsigned connId, ENetError error) { //============================================================================ void NetTransCancelAll (ENetError error) { hsLockGuard(s_critsect); - NetTrans * trans = s_transactions.Head(); - for (; trans; trans = trans->m_link.Next()) + for (NetTrans* trans : s_transactions) { CancelTrans_CS(trans, error); + } } //============================================================================ void NetTransUpdate () { - LISTDECL(NetTrans, m_link) completed; - LISTDECL(NetTrans, m_link) parentCompleted; + std::list completed; + std::list parentCompleted; { hsLockGuard(s_critsect); - NetTrans * next, * trans = s_transactions.Head(); - for (; trans; trans = next) { - next = s_transactions.Next(trans); + for (auto it = s_transactions.begin(); it != s_transactions.end();) { + NetTrans* trans = *it; + // Increment a copy of the iterator here already, + // because the original iterator may be invalidated by an erase call below. + auto next = it; + next++; bool done = false; while (!done) { switch (trans->m_state) { case kTransStateComplete: - if (trans->m_hasSubTrans) - parentCompleted.Link(trans); - else - completed.Link(trans); + s_transactions.erase(it); + if (trans->m_hasSubTrans) { + parentCompleted.push_back(trans); + } else { + completed.push_back(trans); + } done = true; break; @@ -316,18 +328,18 @@ void NetTransUpdate () { DEFAULT_FATAL(trans->m_state); } } + + it = next; } } - // Post completed transactions - while (NetTrans * trans = completed.Head()) { - completed.Unlink(trans); + // Post completed transactions + for (NetTrans* trans : completed) { trans->Post(); trans->UnRef("Lifetime"); } // Post completed parent transactions - while (NetTrans * trans = parentCompleted.Head()) { - parentCompleted.Unlink(trans); + for (NetTrans* trans : parentCompleted) { trans->Post(); trans->UnRef("Lifetime"); } From 86576c501dc0dc58804a905dc459a1c191637b0d Mon Sep 17 00:00:00 2001 From: dgelessus Date: Sun, 20 Aug 2023 21:08:29 +0200 Subject: [PATCH 4/6] Remove no longer used pnUtList (LISTDECL, LIST, LINK) --- .../Plasma/NucleusLib/pnUtils/CMakeLists.txt | 2 - .../NucleusLib/pnUtils/pnUtAllIncludes.h | 1 - .../Plasma/NucleusLib/pnUtils/pnUtList.cpp | 129 ---- Sources/Plasma/NucleusLib/pnUtils/pnUtList.h | 601 ------------------ 4 files changed, 733 deletions(-) delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/pnUtList.cpp delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/pnUtList.h diff --git a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt index 65c510611b..c0aac7a5a4 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt +++ b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt @@ -4,14 +4,12 @@ set(pnUtils_HEADERS pnUtCoreLib.h pnUtAllIncludes.h pnUtCrypt.h - pnUtList.h pnUtStr.h pnUtTime.h ) set(pnUtils_SOURCES pnUtCrypt.cpp - pnUtList.cpp pnUtStr.cpp pnUtTime.cpp ) diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h b/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h index 9fdffb9c68..80d972f07f 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h +++ b/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h @@ -50,7 +50,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pnUtCoreLib.h" // must be first in list -#include "pnUtList.h" #include "pnUtTime.h" #include "pnUtStr.h" #include "pnUtCrypt.h" diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtList.cpp b/Sources/Plasma/NucleusLib/pnUtils/pnUtList.cpp deleted file mode 100644 index aea37ed1ac..0000000000 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtList.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtList.cpp -* -***/ - -#include "Pch.h" -#include "pnUtList.h" - - -/**************************************************************************** -* -* CBaseList -* -***/ - -//=========================================================================== -void CBaseList::Link (CBaseList * list, uint8_t * afterNode, uint8_t * beforeNode, ELinkType linkType, uint8_t * existingNode) { - - // Verify that the two lists share a common link offset - ASSERT(m_linkOffset != LINK_OFFSET_UNINIT); - ASSERT(m_linkOffset == list->m_linkOffset); - - // Verify that the two lists are distinct - CBaseLink * sourceTerminator = &list->m_terminator; - ASSERT(sourceTerminator != &m_terminator); - - // Find the first and last nodes to move from the source list - CBaseLink * afterLink = afterNode ? GetLink(afterNode) : sourceTerminator; - CBaseLink * beforeLink = beforeNode ? GetLink(beforeNode) : sourceTerminator; - CBaseLink * firstLink = afterLink->NextLink(); - CBaseLink * lastLink = beforeLink->m_prevLink; - if (lastLink == afterLink) - return; - ASSERT(firstLink != beforeLink); - - // Store nodes for later use in linking - uint8_t * firstNode = afterLink->m_next; - uint8_t * lastNextNode = lastLink->m_next; - ASSERT(firstNode); - ASSERT(lastNextNode); - - // Find the previous and next nodes in the destination list which will - // bound all of the nodes of the source list - CBaseLink * existingLink = existingNode ? GetLink(existingNode) : &m_terminator; - CBaseLink * prevLink, * nextLink; - switch (linkType) { - - case kListLinkAfter: - prevLink = existingLink; - nextLink = existingLink->NextLink(); - break; - - case kListLinkBefore: - prevLink = existingLink->m_prevLink; - nextLink = existingLink; - break; - - DEFAULT_FATAL(linkType); - - } - - // Update the first and last nodes of the moved range to point to the - // previous and next nodes in the destination list - firstLink->m_prevLink = prevLink; - lastLink->m_next = prevLink->m_next; - - // Update the previous and next nodes in the destination list to point to - // the first and last nodes of the source range - nextLink->m_prevLink = lastLink; - prevLink->m_next = firstNode; - - // Update the before and after links from the source list to point to - // each other - afterLink->m_next = lastNextNode; - beforeLink->m_prevLink = afterLink; - -} - -//=========================================================================== -void CBaseList::UnlinkAll () { - for (CBaseLink * link = m_terminator.m_prevLink, * prev; link != &m_terminator; link = prev) { - prev = link->m_prevLink; - link->InitializeLinksWithOffset(m_linkOffset); - } - m_terminator.InitializeLinksWithOffset(m_linkOffset); -} - diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtList.h b/Sources/Plasma/NucleusLib/pnUtils/pnUtList.h deleted file mode 100644 index 6193f1236c..0000000000 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtList.h +++ /dev/null @@ -1,601 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtList.h -* -***/ - -#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTLIST_H -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTLIST_H - -/**************************************************************************** -* -* Constants -* -***/ - -enum ELinkType { - kListUnlinked, - kListLinkAfter, - kListLinkBefore, - kListHead = kListLinkAfter, - kListTail = kListLinkBefore -}; - - -/**************************************************************************** -* -* Macros -* -***/ - -#define LINK(class) TLink< class > -#define LIST(class) TList< class > -#define LISTDECL(class,field) TListDecl< class, offsetof(class,field) > - - -/**************************************************************************** -* -* Forward declarations -* -***/ - -template -class TLink; - -template -class TList; - - -/**************************************************************************** -* -* CBaseLink -* -***/ - -class CBaseLink { - friend class CBaseList; - - inline static bool TermCheck (uint8_t * ptr); - inline static uint8_t * TermMark (uint8_t * ptr); - inline static uint8_t * TermUnmarkAlways (uint8_t * ptr); - -protected: - CBaseLink * volatile m_prevLink; - uint8_t * volatile m_next; - - inline int CalcLinkOffset () const; - inline void InitializeLinks (); - inline void InitializeLinksWithOffset (int linkOffset); - inline void InsertAfter (uint8_t * node, CBaseLink * prevLink, int linkOffset); - inline void InsertBefore (uint8_t * node, CBaseLink * nextLink); - inline uint8_t * Next () const; - inline uint8_t * NextIgnoreTerm () const; - inline uint8_t * NextUnchecked () const; - inline CBaseLink * NextLink () const; - inline CBaseLink * NextLink (int linkOffset) const; - inline uint8_t * Prev () const; - inline void UnlinkFromNeighbors (); - -public: - inline CBaseLink (); - inline CBaseLink (const CBaseLink & source) = delete; - inline ~CBaseLink (); - CBaseLink & operator= (const CBaseLink & source) = delete; - inline bool IsLinked () const; - inline void Unlink (); - -}; - -//=========================================================================== -CBaseLink::CBaseLink () { - InitializeLinks(); -} - -//=========================================================================== -CBaseLink::~CBaseLink () { - UnlinkFromNeighbors(); -} - -//=========================================================================== -int CBaseLink::CalcLinkOffset () const { - return (int)((uint8_t *)this - m_prevLink->NextIgnoreTerm()); -} - -//=========================================================================== -void CBaseLink::InitializeLinks () { - ASSERT(!((uintptr_t)this & 3)); - m_prevLink = this; - m_next = TermMark((uint8_t *)this); -} - -//=========================================================================== -void CBaseLink::InitializeLinksWithOffset (int linkOffset) { - m_prevLink = this; - m_next = TermMark((uint8_t *)this - linkOffset); -} - -//=========================================================================== -void CBaseLink::InsertAfter (uint8_t * node, CBaseLink * prevLink, int linkOffset) { - UnlinkFromNeighbors(); - m_prevLink = prevLink; - m_next = prevLink->m_next; - prevLink->NextLink(linkOffset)->m_prevLink = this; - prevLink->m_next = node; -} - -//=========================================================================== -void CBaseLink::InsertBefore (uint8_t * node, CBaseLink * nextLink) { - UnlinkFromNeighbors(); - m_prevLink = nextLink->m_prevLink; - m_next = m_prevLink->m_next; - nextLink->m_prevLink->m_next = node; - nextLink->m_prevLink = this; -} - -//=========================================================================== -bool CBaseLink::IsLinked () const { - return (m_prevLink != this); -} - -//=========================================================================== -uint8_t * CBaseLink::Next () const { - return TermCheck(m_next) ? nullptr : m_next; -} - -//=========================================================================== -uint8_t * CBaseLink::NextIgnoreTerm () const { - return TermUnmarkAlways(m_next); -} - -//=========================================================================== -uint8_t * CBaseLink::NextUnchecked () const { - return m_next; -} - -//=========================================================================== -CBaseLink * CBaseLink::NextLink () const { - return (CBaseLink *)(NextIgnoreTerm() + CalcLinkOffset()); -} - -//=========================================================================== -CBaseLink * CBaseLink::NextLink (int linkOffset) const { - ASSERT(linkOffset == CalcLinkOffset()); - return (CBaseLink *)(NextIgnoreTerm() + linkOffset); -} - -//=========================================================================== -uint8_t * CBaseLink::Prev () const { - return m_prevLink->m_prevLink->Next(); -} - -//=========================================================================== -bool CBaseLink::TermCheck (uint8_t * ptr) { - return (uintptr_t)ptr & 1; -} - -//=========================================================================== -uint8_t * CBaseLink::TermMark (uint8_t * ptr) { - // Converts an unmarked pointer to a marked pointer - ASSERT(!TermCheck(ptr)); - return (uint8_t *)((uintptr_t)ptr + 1); -} - -//=========================================================================== -uint8_t * CBaseLink::TermUnmarkAlways (uint8_t * ptr) { - // Returns an unmarked pointer regardless of whether the source pointer - // was marked on unmarked - return (uint8_t *)((uintptr_t)ptr & ~1); -} - -//=========================================================================== -void CBaseLink::Unlink () { - UnlinkFromNeighbors(); - InitializeLinks(); -} - -//=========================================================================== -void CBaseLink::UnlinkFromNeighbors () { - NextLink()->m_prevLink = m_prevLink; - m_prevLink->m_next = m_next; -} - - -/**************************************************************************** -* -* TLink -* -***/ - -template -class TLink : public CBaseLink { - -public: - inline T * Next (); - inline const T * Next () const; - inline T * NextUnchecked (); - inline const T * NextUnchecked () const; - inline T * Prev (); - inline const T * Prev () const; - -}; - -//=========================================================================== -template -T * TLink::Next () { - return (T *)CBaseLink::Next(); -} - -//=========================================================================== -template -const T * TLink::Next () const { - return (const T *)CBaseLink::Next(); -} - -//=========================================================================== -template -T * TLink::NextUnchecked () { - return (T *)CBaseLink::NextUnchecked(); -} - -//=========================================================================== -template -const T * TLink::NextUnchecked () const { - return (const T *)CBaseLink::NextUnchecked(); -} - -//=========================================================================== -template -T * TLink::Prev () { - return (T *)CBaseLink::Prev(); -} - -//=========================================================================== -template -const T * TLink::Prev () const { - return (const T *)CBaseLink::Prev(); -} - - -/**************************************************************************** -* -* CBaseList -* -***/ - -class CBaseList { - -private: - enum { LINK_OFFSET_UNINIT = 0xDDDDDDDD }; - - int m_linkOffset; - CBaseLink m_terminator; - -protected: - inline CBaseLink * GetLink (const uint8_t * node) const; - inline uint8_t * Head () const; - inline bool IsLinked (const uint8_t * node) const; - inline void Link (uint8_t * node, ELinkType linkType, uint8_t * existingNode); - void Link (CBaseList * list, uint8_t * afterNode, uint8_t * beforeNode, ELinkType linkType, uint8_t * existingNode); - inline uint8_t * Next (const uint8_t * node) const; - inline uint8_t * NextUnchecked (const uint8_t * node) const; - inline uint8_t * Prev (uint8_t * node) const; - inline uint8_t * Tail () const; - inline void Unlink (uint8_t * node); - -public: - inline CBaseList (); - inline CBaseList (const CBaseList & source); - inline ~CBaseList (); - inline CBaseList & operator= (const CBaseList & source); - inline void SetLinkOffset (int linkOffset); - void UnlinkAll (); - -}; - -//=========================================================================== -CBaseList::CBaseList () { - m_linkOffset = LINK_OFFSET_UNINIT; -} - -//=========================================================================== -CBaseList::CBaseList (const CBaseList & source) { - m_linkOffset = LINK_OFFSET_UNINIT; -} - -//=========================================================================== -CBaseList::~CBaseList () { - if (m_terminator.IsLinked()) - UnlinkAll(); -} - -//=========================================================================== -CBaseList & CBaseList::operator= (const CBaseList & source) { - return *this; -} - -//=========================================================================== -CBaseLink * CBaseList::GetLink (const uint8_t * node) const { - return (CBaseLink *)(node + m_linkOffset); -} - -//=========================================================================== -uint8_t * CBaseList::Head () const { - return m_terminator.Next(); -} - -//=========================================================================== -bool CBaseList::IsLinked (const uint8_t * node) const { - ASSERT(node); - return GetLink(node)->IsLinked(); -} - -//=========================================================================== -void CBaseList::Link (uint8_t * node, ELinkType linkType, uint8_t * existingNode) { - ASSERT(node != existingNode); - ASSERT(m_linkOffset != LINK_OFFSET_UNINIT); - ASSERT((linkType == kListLinkAfter) || (linkType == kListLinkBefore)); - if (linkType == kListLinkAfter) - GetLink(node)->InsertAfter(node, existingNode ? GetLink(existingNode) : &m_terminator, m_linkOffset); - else - GetLink(node)->InsertBefore(node, existingNode ? GetLink(existingNode) : &m_terminator); -} - -//=========================================================================== -uint8_t * CBaseList::Next (const uint8_t * node) const { - ASSERT(node); - return GetLink(node)->Next(); -} - -//=========================================================================== -uint8_t * CBaseList::NextUnchecked (const uint8_t * node) const { - ASSERT(node); - return GetLink(node)->NextUnchecked(); -} - -//=========================================================================== -uint8_t * CBaseList::Prev (uint8_t * node) const { - ASSERT(node); - return GetLink(node)->Prev(); -} - -//=========================================================================== -void CBaseList::SetLinkOffset (int linkOffset) { - ASSERT(!Head()); - - m_linkOffset = linkOffset; - m_terminator.InitializeLinksWithOffset(linkOffset); -} - -//=========================================================================== -uint8_t * CBaseList::Tail () const { - return m_terminator.Prev(); -} - -//=========================================================================== -void CBaseList::Unlink (uint8_t * node) { - ASSERT(node); - GetLink(node)->Unlink(); -} - - -/**************************************************************************** -* -* TList -* -***/ - -template -class TList : public CBaseList { - -private: - inline T * NewFlags (unsigned flags, ELinkType linkType, T * existingNode, const char file[], int line); - -public: - inline void Clear (); - inline void Delete (T * node); - inline T * Head (); - inline const T * Head () const; - inline bool IsLinked (const T * node) const; - inline void Link (T * node, ELinkType linkType = kListTail, T * existingNode = nullptr); - inline void Link (TList * list, ELinkType linkType = kListTail, T * existingNode = nullptr); - inline void Link (TList * list, T * afterNode, T * beforeNode, ELinkType linkType = kListTail, T * existingNode = nullptr); - inline T * New (ELinkType linkType = kListTail, T * existingNode = nullptr, const char file[] = nullptr, int line = 0); - inline T * NewZero (ELinkType linkType = kListTail, T * existingNode = nullptr, const char file[] = nullptr, int line = 0); - inline T * Next (const T * node); - inline const T * Next (const T * node) const; - inline T * NextUnchecked (const T * node); - inline const T * NextUnchecked (const T * node) const; - inline T * Prev (const T * node); - inline const T * Prev (const T * node) const; - inline T * Tail (); - inline const T * Tail () const; - inline void Unlink (T * node); - -}; - -//=========================================================================== -template -void TList::Clear () { - for (T * curr; (curr = Head()) != nullptr; Delete(curr)) - ; -} - -//=========================================================================== -template -void TList::Delete (T * node) { - delete node; -} - -//=========================================================================== -template -T * TList::Head () { - return (T *)CBaseList::Head(); -} - -//=========================================================================== -template -const T * TList::Head () const { - return (const T *)CBaseList::Head(); -} - -//=========================================================================== -template -bool TList::IsLinked (const T * node) const { - return CBaseList::IsLinked((const uint8_t *)node); -} - -//=========================================================================== -template -void TList::Link (T * node, ELinkType linkType, T * existingNode) { - CBaseList::Link((uint8_t *)node, linkType, (uint8_t *)existingNode); -} - -//=========================================================================== -template -void TList::Link (TList * list, ELinkType linkType, T * existingNode) { - CBaseList::Link(list, nullptr, nullptr, linkType, (uint8_t *)existingNode); -} - -//=========================================================================== -template -void TList::Link (TList * list, T * afterNode, T * beforeNode, ELinkType linkType, T * existingNode) { - CBaseList::Link(list, (uint8_t *)afterNode, (uint8_t *)beforeNode, linkType, (uint8_t *)existingNode); -} - -//=========================================================================== -template -inline T * TList::Next (const T * node) { - return (T *)CBaseList::Next((uint8_t *)node); -} - -//=========================================================================== -template -inline const T * TList::Next (const T * node) const { - return (const T *)CBaseList::Next((uint8_t *)node); -} - -//=========================================================================== -template -inline T * TList::NextUnchecked (const T * node) { - return (T *)CBaseList::NextUnchecked((uint8_t *)node); -} - -//=========================================================================== -template -inline const T * TList::NextUnchecked (const T * node) const { - return (const T *)CBaseList::NextUnchecked((uint8_t *)node); -} - -//=========================================================================== -template -inline T * TList::New (ELinkType linkType, T * existingNode, const char file[], int line) { - return NewFlags(0, linkType, existingNode, file, line); -} - -//=========================================================================== -template -inline T * TList::NewFlags (unsigned flags, ELinkType linkType, T * existingNode, const char file[], int line) { - T * node = new T(); - if (linkType != kListUnlinked) - Link(node, linkType, existingNode); - return node; -} - -//=========================================================================== -template -inline T * TList::NewZero (ELinkType linkType, T * existingNode, const char file[], int line) { - return NewFlags(0, linkType, existingNode, file, line); -} - -//=========================================================================== -template -inline T * TList::Prev (const T * node) { - return (T *)CBaseList::Prev((uint8_t *)node); -} - -//=========================================================================== -template -inline const T * TList::Prev (const T * node) const { - return (const T *)CBaseList::Prev((uint8_t *)node); -} - -//=========================================================================== -template -inline T * TList::Tail () { - return (T *)CBaseList::Tail(); -} - -//=========================================================================== -template -inline const T * TList::Tail () const { - return (const T *)CBaseList::Tail(); -} - -//=========================================================================== -template -inline void TList::Unlink (T * node) { - CBaseList::Unlink((uint8_t *)node); -} - - -/**************************************************************************** -* -* TListDecl -* -***/ - -template -class TListDecl : public TList { - -public: - inline TListDecl (); - -}; - -//=========================================================================== -template -TListDecl::TListDecl () { - this->SetLinkOffset(linkOffset); -} -#endif From bd6b2b284e921b4bd217786665ac6954b7354dcb Mon Sep 17 00:00:00 2001 From: dgelessus Date: Sun, 17 Sep 2023 21:13:37 +0200 Subject: [PATCH 5/6] Move completed transactions more efficiently with std::list::splice --- .../Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp index f92bc1df2d..eea502fba6 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp @@ -275,7 +275,7 @@ void NetTransUpdate () { for (auto it = s_transactions.begin(); it != s_transactions.end();) { NetTrans* trans = *it; // Increment a copy of the iterator here already, - // because the original iterator may be invalidated by an erase call below. + // because the original iterator's meaning may be changed by a splice call below. auto next = it; next++; @@ -283,11 +283,11 @@ void NetTransUpdate () { while (!done) { switch (trans->m_state) { case kTransStateComplete: - s_transactions.erase(it); + // Move the completed transaction out of s_transactions. if (trans->m_hasSubTrans) { - parentCompleted.push_back(trans); + parentCompleted.splice(parentCompleted.end(), s_transactions, it); } else { - completed.push_back(trans); + completed.splice(completed.end(), s_transactions, it); } done = true; break; From f931654d48265dcd54ce7a6e80657d0f5d0cd8cb Mon Sep 17 00:00:00 2001 From: dgelessus Date: Tue, 19 Sep 2023 22:38:41 +0200 Subject: [PATCH 6/6] Lock s_critsect in AbandonConn to be safe Not completely sure if this is actually necessary, but all other code that uses the abandoned and cancelId fields also holds s_critsect. Currently, all callers of AbandonConn already have s_critsect locked, but this is clearer and safer in case the calling code changes. Co-authored-by: Adam Johnson --- Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp | 1 + Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp | 1 + Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp | 1 + .../Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp | 1 + 4 files changed, 4 insertions(+) diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp index bbab8994cb..61fde8e31f 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp @@ -1327,6 +1327,7 @@ static CliAuConn * GetConnIncRef (const char tag[]) { //============================================================================ static void AbandonConn(CliAuConn* conn) { + hsLockGuard(s_critsect); conn->abandoned = true; conn->StopAutoReconnect(); diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp index dff93c44a2..ad12f99dac 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp @@ -275,6 +275,7 @@ static CliFileConn * GetConnIncRef (const char tag[]) { //============================================================================ static void AbandonConn(CliFileConn* conn) { + hsLockGuard(s_critsect); conn->abandoned = true; if (conn->AutoReconnectEnabled()) diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp index e3a6e8c69f..cd5a2972fc 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp @@ -193,6 +193,7 @@ static CliGmConn * GetConnIncRef (const char tag[]) { //============================================================================ static void AbandonConn(CliGmConn* conn) { + hsLockGuard(s_critsect); conn->abandoned = true; if (conn->cancelId) { AsyncSocketConnectCancel(conn->cancelId); diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp index 642ad50954..79233a57e5 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp @@ -220,6 +220,7 @@ static CliGkConn * GetConnIncRef (const char tag[]) { //============================================================================ static void AbandonConn(CliGkConn* conn) { + hsLockGuard(s_critsect); conn->abandoned = true; conn->StopAutoReconnect();