U++ framework
Do not panic. Ask here before giving up.

Home » U++ Library support » U++ MT-multithreading and servers » Threading example for U++
Re: Threading example for U++ [message #10985 is a reply to message #10979] Thu, 09 August 2007 21:59 Go to previous messageGo to previous message
arturbac is currently offline  arturbac
Messages: 91
Registered: May 2007
Location: Reda, Poland
Member

I will put here my fresh one hoever this [C++] implementation is not tested, but Same Generic in C# works well.
[Im at porting stage of some app to c++ so why it is stil not tested]

	template <typename T>
	class ThreadSafeQueue
	{
		class QueueElement;
	public :
			
		int							GetCount() const;
		void						Enqueue(T value);
		T							Dequeue();
		void						FinishWaiting(bool end_job);
		
		ThreadSafeQueue();
		~ThreadSafeQueue();

	private:
		int							m_count;
		QueueElement *				m_head;
		QueueElement *				m_tail;
		Threading::Monitor			m_monitor;
		Threading::CriticalSection	m_lock;
		bool						m_finish_wait;


		class QueueElement
		{
		private:
			friend class				ThreadSafeQueue;

			T							m_value;
			QueueElement *				m_next;

			T							GetValue() const;

			QueueElement(const T & value);
		};
	};



	template <typename T> 
	int ThreadSafeQueue<T>::GetCount() const 
	{ 
		return this->m_count; 
	}

	template <typename T> 
	ThreadSafeQueue<T>::ThreadSafeQueue()
		: m_head(NULL)
		, m_finish_wait(false)
		, m_tail(NULL)
		, m_count(0) 
	{}
	template <typename T> 
	ThreadSafeQueue<T>::~ThreadSafeQueue()
	{
		m_lock.Enter();
		//Clenup remaining items
		if (this->m_head != NULL)
		{ 
			QueueElement *p = this->m_head, *pdel;
			while (p != NULL)
			{
				pdel = p;
				p = p->m_next;
				delete pdel;
			}
			this->m_head = NULL;
			this->m_tail = NULL;
		}
		m_lock.Leave();
	}
	template <typename T> 
	void ThreadSafeQueue<T>::Enqueue(T value)
	{
		m_lock.Enter();
		{
			m_count++;
			QueueElement *enqueue = new QueueElement(value);
			if (m_head == NULL)
			{
				m_head = enqueue;
				m_monitor.Pulse();
			}
			else
				m_tail->m_next = enqueue;
			m_tail = enqueue;
		}
		m_lock.Leave();
	}
	template <typename T> 
	T ThreadSafeQueue<T>::Dequeue()
	{
		QueueElement *dequeued;
		m_lock.Enter();
		{
			while (m_head == NULL && !m_finish_wait)
				m_monitor.Wait();
			if (m_head == NULL && m_finish_wait)
			{
				m_lock.Leave();
				return T(); //End
			}
			m_count--;
			dequeued = m_head;
			m_head = m_head->m_next;
		}
		m_lock.Leave();
		T res(dequeued->GetValue());
		delete dequeued;
		return res;
	}
	template <typename T> 
	void ThreadSafeQueue<T>::FinishWaiting(bool end_job)
	{
		m_lock.Enter();
		{
			m_finish_wait = end_job;
			m_monitor.Pulse();
		}
		m_lock.Leave();
	}

	template <typename T> 
	ThreadSafeQueue<T>::QueueElement::QueueElement(const T & value)
		: m_next(NULL)
		, m_value(value)
	{}

	template <typename T> 
	T ThreadSafeQueue<T>::QueueElement::GetValue() const 
	{ 
		return this->m_value; 
	}


	class Monitor : public CriticalSection
	{
	public:

		Monitor();

		void						Wait() throw(...);
		void						Pulse() throw(...);

	private:
		int							m_QueueSize;
		CriticalSection				m_lock;
		Semaphore					m_waiting;
	};

	Monitor::Monitor() : m_QueueSize(0) {}
	void Monitor::Wait()
	{
		m_lock.Enter();
		m_QueueSize++;
		m_lock.Leave();
		m_waiting.Wait();
	}  
	void Monitor::Pulse()
	{
		m_lock.Enter();
		if (m_QueueSize > 0)
			m_waiting.Release();
		m_lock.Leave();
	}
 
Read Message icon1.gif
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message icon1.gif
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message icon5.gif
Read Message
Read Message
Previous Topic: Non-Blocking socket example
Next Topic: typo in manual on web
Goto Forum:
  


Current Time: Sat Jun 20 17:22:09 GMT+2 2026

Total time taken to generate the page: 0.00786 seconds