Browse Source

Reintroduce (and enforce use of) hsLockFor{Reading,Writing}

Michael Hansen 10 years ago
parent
commit
474b54396b
  1. 37
      Sources/Plasma/CoreLib/hsThread.h
  2. 24
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp
  3. 28
      Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp

37
Sources/Plasma/CoreLib/hsThread.h

@ -207,6 +207,7 @@ class hsReaderWriterLock
public: public:
hsReaderWriterLock() : fReaderCount(0), fWriterSem(1) { } hsReaderWriterLock() : fReaderCount(0), fWriterSem(1) { }
private:
void LockForReading() void LockForReading()
{ {
// Don't allow us to start reading if there's still an active writer // Don't allow us to start reading if there's still an active writer
@ -241,10 +242,44 @@ public:
fReaderLock.unlock(); fReaderLock.unlock();
} }
private:
std::atomic<int> fReaderCount; std::atomic<int> fReaderCount;
std::mutex fReaderLock; std::mutex fReaderLock;
hsSemaphore fWriterSem; 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 #endif

24
Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp

@ -340,11 +340,8 @@ void AsyncSocketRegisterNotifyProc (
ct->productId = productId; ct->productId = productId;
ct->flags = kConnHashFlagsIgnore; ct->flags = kConnHashFlagsIgnore;
s_notifyProcLock.LockForWriting(); hsLockForWriting lock(s_notifyProcLock);
{ s_notifyProcs.Add(ct);
s_notifyProcs.Add(ct);
}
s_notifyProcLock.UnlockForWriting();
} }
//=========================================================================== //===========================================================================
@ -365,8 +362,9 @@ void AsyncSocketUnregisterNotifyProc (
hash.flags = kConnHashFlagsExactMatch; hash.flags = kConnHashFlagsExactMatch;
ISocketConnType * scan; ISocketConnType * scan;
s_notifyProcLock.LockForWriting();
{ {
hsLockForWriting lock(s_notifyProcLock);
scan = s_notifyProcs.Find(hash); scan = s_notifyProcs.Find(hash);
for (; scan; scan = s_notifyProcs.FindNext(hash, scan)) { for (; scan; scan = s_notifyProcs.FindNext(hash, scan)) {
if (scan->notifyProc != notifyProc) if (scan->notifyProc != notifyProc)
@ -377,7 +375,6 @@ void AsyncSocketUnregisterNotifyProc (
break; break;
} }
} }
s_notifyProcLock.UnlockForWriting();
// perform memory deallocation outside the lock // perform memory deallocation outside the lock
delete scan; delete scan;
@ -403,12 +400,13 @@ FAsyncNotifySocketProc AsyncSocketFindNotifyProc (
// Lookup notifyProc based on connType // Lookup notifyProc based on connType
FAsyncNotifySocketProc proc; FAsyncNotifySocketProc proc;
s_notifyProcLock.LockForReading(); {
if (const ISocketConnType * scan = s_notifyProcs.Find(hash)) hsLockForReading lock(s_notifyProcLock);
proc = scan->notifyProc; if (const ISocketConnType * scan = s_notifyProcs.Find(hash))
else proc = scan->notifyProc;
proc = nil; else
s_notifyProcLock.UnlockForReading(); proc = nullptr;
}
if (!proc) if (!proc)
break; break;

28
Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp

@ -283,12 +283,11 @@ static void UnlinkAndAbandonConn_CS (CliFileConn * conn) {
needsDecref = false; needsDecref = false;
} }
else { else {
conn->sockLock.LockForReading(); hsLockForReading lock(conn->sockLock);
if (conn->sock) { if (conn->sock) {
AsyncSocketDisconnect(conn->sock, true); AsyncSocketDisconnect(conn->sock, true);
needsDecref = false; needsDecref = false;
} }
conn->sockLock.UnlockForReading();
} }
if (needsDecref) { if (needsDecref) {
conn->UnRef("Lifetime"); conn->UnRef("Lifetime");
@ -311,9 +310,8 @@ static void NotifyConnSocketConnect (CliFileConn * conn) {
} }
else else
{ {
conn->sockLock.LockForReading(); hsLockForReading lock(conn->sockLock);
AsyncSocketDisconnect(conn->sock, true); AsyncSocketDisconnect(conn->sock, true);
conn->sockLock.UnlockForReading();
} }
} }
s_critsect.Leave(); s_critsect.Leave();
@ -468,9 +466,8 @@ static bool SocketNotifyCallback (
*userState = conn; *userState = conn;
s_critsect.Enter(); s_critsect.Enter();
{ {
conn->sockLock.LockForWriting(); hsLockForWriting lock(conn->sockLock);
conn->sock = sock; conn->sock = sock;
conn->sockLock.UnlockForWriting();
conn->cancelId = 0; conn->cancelId = 0;
} }
s_critsect.Leave(); s_critsect.Leave();
@ -697,9 +694,11 @@ void CliFileConn::AutoPing () {
Ref("PingTimer"); Ref("PingTimer");
timerCritsect.Enter(); timerCritsect.Enter();
{ {
sockLock.LockForReading(); unsigned timerPeriod;
unsigned timerPeriod = sock ? 0 : kAsyncTimeInfinite; {
sockLock.UnlockForReading(); hsLockForReading lock(sockLock);
timerPeriod = sock ? 0 : kAsyncTimeInfinite;
}
AsyncTimerCreate( AsyncTimerCreate(
&pingTimer, &pingTimer,
@ -725,7 +724,8 @@ void CliFileConn::StopAutoPing () {
//============================================================================ //============================================================================
void CliFileConn::TimerPing () { void CliFileConn::TimerPing () {
sockLock.LockForReading(); hsLockForReading lock(sockLock);
for (;;) { for (;;) {
if (!sock) // make sure it exists if (!sock) // make sure it exists
break; break;
@ -752,18 +752,16 @@ void CliFileConn::TimerPing () {
} }
break; break;
} }
sockLock.UnlockForReading();
} }
//============================================================================ //============================================================================
void CliFileConn::Destroy () { void CliFileConn::Destroy () {
AsyncSocket oldSock = nil; AsyncSocket oldSock = nil;
sockLock.LockForWriting();
{ {
hsLockForWriting lock(sockLock);
SWAP(oldSock, sock); SWAP(oldSock, sock);
} }
sockLock.UnlockForWriting();
if (oldSock) if (oldSock)
AsyncSocketDelete(oldSock); AsyncSocketDelete(oldSock);
@ -772,11 +770,11 @@ void CliFileConn::Destroy () {
//============================================================================ //============================================================================
void CliFileConn::Send (const void * data, unsigned bytes) { void CliFileConn::Send (const void * data, unsigned bytes) {
sockLock.LockForReading(); hsLockForReading lock(sockLock);
if (sock) { if (sock) {
AsyncSocketSend(sock, data, bytes); AsyncSocketSend(sock, data, bytes);
} }
sockLock.UnlockForReading();
} }
//============================================================================ //============================================================================

Loading…
Cancel
Save