Click here to Skip to main content
15,881,836 members
Articles / Programming Languages / C++

Single-threaded concurrency model design

Rate me:
Please Sign up or sign in to vote.
4.71/5 (7 votes)
12 Jul 2009CPOL20 min read 32K   359   25  
A lightweight library to support single-threaded concurrency with multiple components.
#pragma once
#include "GuardObjs.h"
#include "ContainersInl.h"

class ThreadCtx {

	static __declspec(thread) ThreadCtx* s_pCtx;
	static ThreadCtx& CTX() { ASSERT(s_pCtx); return *s_pCtx; }

	struct GBaseH_SignaledNode :public GObj::GBaseH_CoreNull<char> {
		void InternalDestroy() { VERIFY(CTX().m_nSignaled-- > 0); }
	};
	typedef GObj::GObj_T<GBaseH_SignaledNode> Signal_G;

public:
	class Schedule;
	class ScheduleTimer;
	class ScheduleHandle;

private:
	Container::TreeEx<Container::TreeOrd, ScheduleTimer> m_treeTimers;
	Container::ListEx<Container::ListHT, ScheduleHandle> m_lstHandle;
	size_t m_nApc;
	size_t m_nMsg;

	size_t m_nSignaled;

	DWORD PerfWait(HANDLE*, DWORD, DWORD dwTimeout);
	Schedule* Wait(bool& bApc, bool& bMsg);
	void WaitOnce();
	void DispatchMessages();

public:

	ThreadCtx();
	~ThreadCtx();

	class Schedule
	{
		Signal_G m_Signal;
	public:

		bool Wait();

		bool get_Signaled() const { return m_Signal; }
		void put_Signaled(bool bVal);
		__declspec(property(get=get_Signaled,put=put_Signaled)) bool _Signaled;

		virtual void OnSchedule(); // default sets Signaled

	protected:
		friend class ThreadCtx;
	};

	class ScheduleHandle
		:public Schedule
		,public Container::NodeEx<Container::ListHT, ScheduleHandle>
	{
		HANDLE m_hHandle;
	public:
		ScheduleHandle() :m_hHandle(NULL) {}
		~ScheduleHandle() { RemoveFromList(); }

		void put_Handle(HANDLE hVal);
		HANDLE get_Handle() const { return m_hHandle; }
		__declspec(property(get=get_Handle,put=put_Handle)) HANDLE _Handle;
	private:
		void RemoveFromList();
	};

	class ScheduleTimer
		:public Schedule
		,public Container::TreeOrd::Node
	{
	public:
		ScheduleTimer() { m_Key = 0; }
		~ScheduleTimer() { KillTimer(); }
		void KillTimer() { _Timeout = INFINITE; }

		ULONG get_Timeout() const;
		void put_Timeout(ULONG);
		__declspec(property(get=get_Timeout,put=put_Timeout)) ULONG _Timeout;

		bool IsTimerSet() const { return 0 != m_Key; }
	};

	struct NeedApc {
		NeedApc() { CTX().m_nApc++; }
		~NeedApc() { VERIFY(CTX().m_nApc--); }
	};

	struct NeedMsg {
		NeedMsg() { CTX().m_nMsg++; }
		~NeedMsg() { VERIFY(CTX().m_nMsg--); }
	};
};

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
Software Developer (Senior)
Israel Israel
My name is Vladislav Gelfer, I was born in Kiev (former Soviet Union), since 1993 I live in Israel.
In programming I'm interested mostly in low-level, OOP design, DSP and multimedia.
Besides of the programming I like physics, math, digital photography.

Comments and Discussions