Click here to Skip to main content
15,896,154 members
Articles / Desktop Programming / MFC

A class to synchronise thread completions

Rate me:
Please Sign up or sign in to vote.
4.70/5 (29 votes)
15 Oct 2004CPOL14 min read 121K   2.5K   69  
Synchronising thread completion the easy way
#pragma once

namespace rendevouz
{
#define DEREF(data) \
	rendevouz::CBaseThread *pThread = (rendevouz::CBaseThread *) data; \
	ASSERT(pThread); \
	ASSERT_KINDOF(CBaseThread, pThread);

class CBaseThread : public CObject
{
	DECLARE_DYNAMIC(CBaseThread);
public:
				CBaseThread(HANDLE hStopEvent, volatile bool *bStop, unsigned(__stdcall *thread)(void *), bool bWait = false, LPVOID data = NULL);
				~CBaseThread();

	bool		IsWaiting()	const		{ return m_bWaiting; }
	volatile bool Stop() const			{ return *m_bStop; }
	HANDLE		StopEvent() const		{ return m_hStopEvent; }
	HANDLE		ThreadHandle() const	{ return m_hThreadHandle; }
	LPVOID		UserData() const		{ return m_pvUserData; }

	virtual bool Wait(DWORD dwTimeout = INFINITE) const;
	bool		Run() const				{ return ResumeThread(m_hThreadHandle) == 1; }

	UINT		ThreadID() const		{ return m_uiThreadID; }

protected:
	LPVOID		m_pvUserData;
	HANDLE		m_hStopEvent,
				m_hThreadHandle;
	volatile bool *m_bStop,
				m_bWaiting;
	UINT		m_uiThreadID;
};

class CUserThread : public CBaseThread
{
	DECLARE_DYNAMIC(CUserThread);
public:
				CUserThread(unsigned(__stdcall *thread)(void *), bool bWait = false, LPVOID data = NULL);
	virtual		~CUserThread();

	void		TerminateThread();

private:
	volatile bool m_bStopVar;
};

class CSyncRendevouz : public CObject
{
	DECLARE_DYNAMIC(CSyncRendevouz);
public:
				CSyncRendevouz(void);
				~CSyncRendevouz(void);

	void		Stop()					{ m_bStop = TRUE; SetEvent(m_hStopEvent); }
	virtual bool Wait(DWORD dwTimeout = INFINITE);

	bool		AddThread(unsigned(__stdcall *thread)(void *), bool bWait = false, LPVOID data = NULL);
	bool		AddHandle(HANDLE hHandle);

protected:
	CArray<HANDLE, HANDLE>m_handleArray;
	CList<CBaseThread*, CBaseThread *> m_threads;
	HANDLE		m_hStopEvent;
	volatile bool m_bStop;
};

class CAsyncRendevouz : public CSyncRendevouz
{
	DECLARE_DYNAMIC(CAsyncRendevouz);
public:
				CAsyncRendevouz(HWND wndTarget, UINT uiMsg, LPVOID pvUserData = NULL);
				~CAsyncRendevouz();

	virtual bool Wait(DWORD dwTimeout = INFINITE);

private:
	static unsigned __stdcall WaitProc(LPVOID data);

	HWND		m_wndTarget;
	UINT		m_uiMsg;
	DWORD		m_dwTimeout;
	LPVOID		m_pvUserData;
	CBaseThread *m_pThread;
};
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I've been programming for 35 years - started in machine language on the National Semiconductor SC/MP chip, moved via the 8080 to the Z80 - graduated through HP Rocky Mountain Basic and HPL - then to C and C++ and now C#.

I used (30 or so years ago when I worked for Hewlett Packard) to repair HP Oscilloscopes and Spectrum Analysers - for a while there I was the one repairing DC to daylight SpecAns in the Asia Pacific area.

Afterward I was the fourth team member added to the Australia Post EPOS project at Unisys Australia. We grew to become an A$400 million project. I wrote a few device drivers for the project under Microsoft OS/2 v 1.3 - did hardware qualification and was part of the rollout team dealing directly with the customer.

Born and bred in Melbourne Australia, now living in Scottsdale Arizona USA, became a US Citizen on September 29th, 2006.

I work for a medical insurance broker, learning how to create ASP.NET websites in VB.Net and C#. It's all good.

Oh, I'm also a Kentucky Colonel. http://www.kycolonels.org

Comments and Discussions