/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __ASYNC_CALL_QUEUE_THREAD__ #define __ASYNC_CALL_QUEUE_THREAD__ #include "async/async_call_queue.h" #include "thread/thread_event.h" namespace GS { namespace Threading { /*! @short A worker thread whose sole purpose is to process its async call queue. @author Emmanuel Julien (ejulien@owloh.com) */ class ASyncCallQueueThread : public Thread { Atomic32 acqt_running; Event queue_event; ASync::CallQueue call_queue; public: virtual void OnIdle() {} virtual void Execute() { for (acqt_running.Set(1); acqt_running.Get() != 2; ) { call_queue.ExecuteAll(); OnIdle(); queue_event.Wait(); } acqt_running.Set(0); } void Stop() { if (acqt_running.Get() != 0) { acqt_running.Set(2); queue_event.Trigger(); while (acqt_running.Get() != 0); // spinlock } } template void QueueMemberCall(I i, F fn) { call_queue.QueueMemberCall(i, fn); queue_event.Trigger(); } template void QueueMemberCall(I i, F fn, const A1 &a1) { call_queue.QueueMemberCall(i, fn, a1); queue_event.Trigger(); } template void QueueMemberCall(I i, F fn, const A1 &a1, const A2 &a2) { call_queue.QueueMemberCall(i, fn, a1, a2); queue_event.Trigger(); } template void QueueMemberCall(I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3) { call_queue.QueueMemberCall(i, fn, a1, a2, a3); queue_event.Trigger(); } template void QueueMemberCall(I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) { call_queue.QueueMemberCall(i, fn, a1, a2, a3, a4); queue_event.Trigger(); } /// Queue a member call, return the value in a future. template void QueueMemberCall(ASync::Future &f, I i, F fn) { call_queue.QueueMemberCall(f, i, fn); queue_event.Trigger(); } template void QueueMemberCall(ASync::Future &f, I i, F fn, const A1 &a1) { call_queue.QueueMemberCall(f, i, fn, a1); queue_event.Trigger(); } template void QueueMemberCall(ASync::Future &f, I i, F fn, const A1 &a1, const A2 &a2) { call_queue.QueueMemberCall(f, i, fn, a1, a2); queue_event.Trigger(); } template void QueueMemberCall(ASync::Future &f, I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3) { call_queue.QueueMemberCall(f, i, fn, a1, a2, a3); queue_event.Trigger(); } template void QueueMemberCall(ASync::Future &f, I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) { call_queue.QueueMemberCall(f, i, fn, a1, a2, a3, a4); queue_event.Trigger(); } virtual ~ASyncCallQueueThread() { Stop(); } }; } // Threading } // GS #endif // __ASYNC_CALL_QUEUE_THREAD__