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:
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<int> 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

24
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;

28
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();
}
//============================================================================

Loading…
Cancel
Save