mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-18 11:19:10 +00:00
Reintroduce (and enforce use of) hsLockFor{Reading,Writing}
This commit is contained in:
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
Reference in New Issue
Block a user