From 474b54396b88be9c956f8a0e5211a9571acf582e Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sat, 26 Jul 2014 13:05:43 -0700 Subject: [PATCH] Reintroduce (and enforce use of) hsLockFor{Reading,Writing} --- Sources/Plasma/CoreLib/hsThread.h | 37 ++++++++++++++++++- .../NucleusLib/pnAsyncCoreExe/pnAceIo.cpp | 24 ++++++------ .../plNetGameLib/Private/plNglFile.cpp | 28 +++++++------- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/Sources/Plasma/CoreLib/hsThread.h b/Sources/Plasma/CoreLib/hsThread.h index 08a5c388..c49518cd 100644 --- a/Sources/Plasma/CoreLib/hsThread.h +++ b/Sources/Plasma/CoreLib/hsThread.h @@ -207,6 +207,7 @@ class hsReaderWriterLock public: hsReaderWriterLock() : fReaderCount(0), fWriterSem(1) { } +private: void LockForReading() { // Don't allow us to start reading if there's still an active writer @@ -241,10 +242,44 @@ public: fReaderLock.unlock(); } -private: std::atomic fReaderCount; std::mutex fReaderLock; hsSemaphore fWriterSem; + + friend class hsLockForReading; + friend class hsLockForWriting; +}; + +class hsLockForReading +{ + hsReaderWriterLock& fLock; + +public: + hsLockForReading(hsReaderWriterLock& lock) : fLock(lock) + { + fLock.LockForReading(); + } + + ~hsLockForReading() + { + fLock.UnlockForReading(); + } +}; + +class hsLockForWriting +{ + hsReaderWriterLock& fLock; + +public: + hsLockForWriting(hsReaderWriterLock& lock) : fLock(lock) + { + fLock.LockForWriting(); + } + + ~hsLockForWriting() + { + fLock.UnlockForWriting(); + } }; #endif diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp index 294c774c..29f3de0d 100644 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp +++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp @@ -340,11 +340,8 @@ void AsyncSocketRegisterNotifyProc ( ct->productId = productId; ct->flags = kConnHashFlagsIgnore; - s_notifyProcLock.LockForWriting(); - { - s_notifyProcs.Add(ct); - } - s_notifyProcLock.UnlockForWriting(); + hsLockForWriting lock(s_notifyProcLock); + s_notifyProcs.Add(ct); } //=========================================================================== @@ -365,8 +362,9 @@ void AsyncSocketUnregisterNotifyProc ( hash.flags = kConnHashFlagsExactMatch; ISocketConnType * scan; - s_notifyProcLock.LockForWriting(); { + hsLockForWriting lock(s_notifyProcLock); + scan = s_notifyProcs.Find(hash); for (; scan; scan = s_notifyProcs.FindNext(hash, scan)) { if (scan->notifyProc != notifyProc) @@ -377,7 +375,6 @@ void AsyncSocketUnregisterNotifyProc ( break; } } - s_notifyProcLock.UnlockForWriting(); // perform memory deallocation outside the lock delete scan; @@ -403,12 +400,13 @@ FAsyncNotifySocketProc AsyncSocketFindNotifyProc ( // Lookup notifyProc based on connType FAsyncNotifySocketProc proc; - s_notifyProcLock.LockForReading(); - if (const ISocketConnType * scan = s_notifyProcs.Find(hash)) - proc = scan->notifyProc; - else - proc = nil; - s_notifyProcLock.UnlockForReading(); + { + hsLockForReading lock(s_notifyProcLock); + if (const ISocketConnType * scan = s_notifyProcs.Find(hash)) + proc = scan->notifyProc; + else + proc = nullptr; + } if (!proc) break; diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp index fe54e05d..8086f4c5 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp @@ -283,12 +283,11 @@ static void UnlinkAndAbandonConn_CS (CliFileConn * conn) { needsDecref = false; } else { - conn->sockLock.LockForReading(); + hsLockForReading lock(conn->sockLock); if (conn->sock) { AsyncSocketDisconnect(conn->sock, true); needsDecref = false; } - conn->sockLock.UnlockForReading(); } if (needsDecref) { conn->UnRef("Lifetime"); @@ -311,9 +310,8 @@ static void NotifyConnSocketConnect (CliFileConn * conn) { } else { - conn->sockLock.LockForReading(); + hsLockForReading lock(conn->sockLock); AsyncSocketDisconnect(conn->sock, true); - conn->sockLock.UnlockForReading(); } } s_critsect.Leave(); @@ -468,9 +466,8 @@ static bool SocketNotifyCallback ( *userState = conn; s_critsect.Enter(); { - conn->sockLock.LockForWriting(); + hsLockForWriting lock(conn->sockLock); conn->sock = sock; - conn->sockLock.UnlockForWriting(); conn->cancelId = 0; } s_critsect.Leave(); @@ -697,9 +694,11 @@ void CliFileConn::AutoPing () { Ref("PingTimer"); timerCritsect.Enter(); { - sockLock.LockForReading(); - unsigned timerPeriod = sock ? 0 : kAsyncTimeInfinite; - sockLock.UnlockForReading(); + unsigned timerPeriod; + { + hsLockForReading lock(sockLock); + timerPeriod = sock ? 0 : kAsyncTimeInfinite; + } AsyncTimerCreate( &pingTimer, @@ -725,7 +724,8 @@ void CliFileConn::StopAutoPing () { //============================================================================ void CliFileConn::TimerPing () { - sockLock.LockForReading(); + hsLockForReading lock(sockLock); + for (;;) { if (!sock) // make sure it exists break; @@ -752,18 +752,16 @@ void CliFileConn::TimerPing () { } break; } - sockLock.UnlockForReading(); } //============================================================================ void CliFileConn::Destroy () { AsyncSocket oldSock = nil; - sockLock.LockForWriting(); { + hsLockForWriting lock(sockLock); SWAP(oldSock, sock); } - sockLock.UnlockForWriting(); if (oldSock) AsyncSocketDelete(oldSock); @@ -772,11 +770,11 @@ void CliFileConn::Destroy () { //============================================================================ void CliFileConn::Send (const void * data, unsigned bytes) { - sockLock.LockForReading(); + hsLockForReading lock(sockLock); + if (sock) { AsyncSocketSend(sock, data, bytes); } - sockLock.UnlockForReading(); } //============================================================================