Interlocking APIs

Interlocking is one on the smallest locking mechanism available in Win32. It works on a variable and updates the variable in atomic way. This ensures variable is locked and updated. Synchronization is maintained with respect to multiple thread context. It uses processor instruction set to do an atomic operation.

LONG WINAPI InterlockedIncrement(LPLONG lpAddend);
LONG WINAPI InterlockedDecrement(LPLONG lpAddend);
LONG WINAPI InterlockedExchange(LPLONG Target, LONG Value);
PVOID WINAPI InterlockedCompareExchange(PVOID *Destination,PVOID Exchange,PVOID Comperand);
LONG WINAPI InterlockedExchangeAdd(LPLONG Addend,LONG Value);

Interlocking APIs cannot be used in multiple number of statements. MFC synch objects are used for this purrpose and we are going to discuss more in next section.

CSyncObject class

The base class of all synchonization classes is CSyncObject. CCriticalSection, CEvent, CMutex, CSemaphore etc are derived from this class.

class CSyncObject : public CObject
{
	DECLARE_DYNAMIC(CSyncObject)

// Constructor
public:
	CSyncObject(LPCTSTR pstrName);

// Attributes
public:
	operator HANDLE() const;
	HANDLE  m_hObject;

// Operations
	virtual BOOL Lock(DWORD dwTimeout = INFINITE);
	virtual BOOL Unlock() = 0;
	virtual BOOL Unlock(LONG /* lCount */, LPLONG /* lpPrevCount=NULL */)
		{ return TRUE; }

// Implementation
public:
	virtual ~CSyncObject();

	friend class CSingleLock;
	friend class CMultiLock;
};

Critical section

shared resources can be protected with critical sections. A small block of code can be put under critical section where shared resources are getting accessed.

class CCriticalSection : public CSyncObject
{
	DECLARE_DYNAMIC(CCriticalSection)

// Constructor
public:
	CCriticalSection();

// Attributes
public:
	operator CRITICAL_SECTION*();
	CRITICAL_SECTION m_sect;

// Operations
public:
	BOOL Unlock();
	BOOL Lock();
	BOOL Lock(DWORD dwTimeout);

// Implementation
public:
	virtual ~CCriticalSection();
};

CEvent

Event is mainly used for asynchronous notifaction of a work. Main process creates a thread for doing the actual work and creates an event. Main thread waits on the event to be signaled. Worker thread completes the work and signals the event.

class CEvent : public CSyncObject
{
	DECLARE_DYNAMIC(CEvent)

// Constructor
public:
	CEvent(BOOL bInitiallyOwn = FALSE, BOOL bManualReset = FALSE,
		LPCTSTR lpszNAme = NULL, LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);

// Operations
public:
	BOOL SetEvent();
	BOOL PulseEvent();
	BOOL ResetEvent();
	BOOL Unlock();

// Implementation
public:
	virtual ~CEvent();
};

CEvent is a named object thus can be used accross multiple process.

CMutex

Mutex is the lock for two or more mutual execution. Mutex can have two state locked/owned or unlocked/unowned. One thread can lock a mutex and other threads will wait for unlock. Once the owning thead unlocks the other threads can own and lock.

class CMutex : public CSyncObject
{
	DECLARE_DYNAMIC(CMutex)

// Constructor
public:
	CMutex(BOOL bInitiallyOwn = FALSE, LPCTSTR lpszName = NULL,
		LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);

// Implementation
public:
	virtual ~CMutex();
	BOOL Unlock();
};

CMutex is a named object thus can be used accross multiple process.

CSemaphore

Semaphore is the lock for mutiple state. Multiple states are represented in max count variable passed in constructor. A semaphore with binary state or lock(0) and unlock(1) is same as CMutex.

class CSemaphore : public CSyncObject
{
	DECLARE_DYNAMIC(CSemaphore)

// Constructor
public:
	CSemaphore(LONG lInitialCount = 1, LONG lMaxCount = 1,
		LPCTSTR pstrName=NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL);

// Implementation
public:
	virtual ~CSemaphore();
	virtual BOOL Unlock();
	virtual BOOL Unlock(LONG lCount, LPLONG lprevCount = NULL);
};

CSemaphore is a named object thus can be used accross multiple process.

About our authors: Team EQA

Further readings

Where is WinMain() function in MFC application ?

MFC hides WinMain in its framework and includes source file on WinMain(). This explains how framework calls global CWinApp::Initinstance() from entry WinMain.

What is the utility of CWinApp class?

This is constructed during global C++ objects are constructed and is already available when Windows calls the WinMain function, which is supplied by the ...

Basic steps in Win32 GUI Application with source code.

Define a custom Window class structure, Register the class name, CreateWindow, Show windows and write message get and dispatch loop statements. Define the Window CallBack procedure and write the handlers.

What is a Window CallBack procedure and what is its utility?

DispatchMessage() is a API which indirectly triggers the Window CallBack procedure. Message structure members from this function are passed to the CallBack procedure. CallBack procedure should implement event handlers depending on the need of the application.

What are LPARAM and WPARAM in window proc function?

LPARAM and WPARAM are the two parameters in Window CallBack procedure. They signifies parameters of various events. They are used in handing individual events.

What are the basic steps of a typical MFC based application?

We need to write WinMain and need to follow all these in a Win32 application. However we need not to write much if we are writing an application with MFC ...

#