I think the article is based on a fundamental misunderstanding of what CSingleLock is for and how to use it.
You cannot block the same CSingleLock multiple times, but you should not. CSingleLock, as the name implies, is designed to block something else.
Each CSingleLock controls one lock on some other object (for example, the CCriticalSection that you pass to it at build time), in order to automatically release this lock when CSingleLock goes out of scope.
If you want to lock the base object several times, you will use several CSingleLocks; you will not use one CSingleLock and try to block it several times.
Invalid (example):
CCriticalSection crit; CSingleLock lock(&crit); lock.Lock(); lock.Lock(); lock.Unlock(); lock.Unlock();
On right:
CCriticalSection crit; CSingleLock lock1(&crit); CSingleLock lock2(&crit); lock1.Lock(); lock2.Lock(); lock2.Unlock(); lock1.Unlock();
Even better (so you get RAII):
CCriticalSection crit; // Scope the objects { CSingleLock lock1(&crit, TRUE); // TRUE means it (tries to) locks immediately. // Do stuff which needs the lock (if IsLocked returns success) CSingleLock lock2(&crit, TRUE); // Do stuff which needs the lock (if IsLocked returns success) } // crit is unlocked now.
(Of course, you would never intentionally get two locks in the same critical section in one block. This usually happens only as a result of calling functions that receive the lock, while inside something else that already has its own lock.)
(In addition, you should check CSingleLock.IsLocked to verify that the lock was successful. I left these checks for brevity and because they were excluded from the original example.)
If the CCriticalSection itself suffers from the same problem, then this is certainly a problem, but he did not provide any evidence of what I see. (Maybe I missed something. I cannot find the source for CCriticalSection in my MFC setup to check this path.)