Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Single-threaded concurrency model design

, 12 Jul 2009 CPOL
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)

Share

About the Author

valdok
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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150301.1 | Last Updated 12 Jul 2009
Article Copyright 2009 by valdok
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid