#include "stdafx.h" // // THERE CAN BE NO TRACE STATEMENTS USING XTRACE IN THIS CLASS - IT CAUSES RECIURSION // CLock::CLock(void) { try { cs_valid = true; cs_thread_id = 0; cs_lock = new CRITICAL_SECTION; m_ref = 0; // Initialize the critical section one time only. InitializeCriticalSection(cs_lock); } catch(...) { cs_valid = false; } } CLock::~CLock(void) { Unlock(); DeleteCriticalSection(cs_lock); delete cs_lock; } void CLock::Lock() { if(GetCurrentThreadId() != cs_thread_id) { // XTRACE1("Waiting for critical section, GetCurrentThreadId=(%#8.8x)\n", GetCurrentThreadId()); } // // NOT IN CRITICAL SECTION // EnterCriticalSection(cs_lock); // // IN CRITICAL SECTION // // copy thread id // cs_thread_id = GetCurrentThreadId(); // // up ref count // InterlockedIncrement(&m_ref); //XTRACE2("Lock acquired, GetCurrentThreadId=(%#8.8x), refcount=%d\n", GetCurrentThreadId(), int(m_ref)); } void CLock::Unlock() { if(cs_thread_id == GetCurrentThreadId()) { long last = m_ref; // // CRITICAL SECTION HELD BY THREAD // if(InterlockedDecrement(&m_ref) >= 0) { // // must be called once for each call to EnterCriticalSection // LeaveCriticalSection(cs_lock); //XTRACE2("Lock released, GetCurrentThreadId=(%#8.8x), refcount=%d\n", GetCurrentThreadId(), int(m_ref)); //if(last == 1) ///{ // XTRACE("Lock freed\n"); //} } else { InterlockedExchange(&m_ref, 0); } } }