Line data Source code
1 : // Copyright 2024 Accenture. 2 : 3 : /** 4 : * \ingroup async 5 : */ 6 : #ifndef GUARD_ECCAA06F_729C_4CDD_9C3B_67D97352DE9E 7 : #define GUARD_ECCAA06F_729C_4CDD_9C3B_67D97352DE9E 8 : 9 : #include "async/Queue.h" 10 : 11 : #include <platform/config.h> 12 : 13 : namespace async 14 : { 15 : /** 16 : * A template class that enables the enqueuing and execution of Runnables. It leverages an 17 : * EventPolicy, making it suitable for event-driven applications. 18 : * 19 : * \tparam Runnable Type of functions, that will be executed. 20 : * \tparam EventPolicy EventPolicy is derived from EventDispatcher. Method enqueue will set Event, 21 : * specified in EventPolicy. 22 : */ 23 : template<typename Runnable, typename EventPolicy, typename Lock> 24 : class RunnableExecutor 25 : { 26 : public: 27 : explicit RunnableExecutor(typename EventPolicy::EventDispatcherType& eventDispatcher); 28 : 29 : void init(); 30 : void shutdown(); 31 : 32 : /** 33 : * Places a Runnable in the internal queue and sets the event in the EventDispatcher. When 34 : * handleEvents is called on the EventDispatcher, all Runnables in the queue are executed 35 : * sequentially, and the queue is emptied. 36 : * \param runnable Runnable to be executed 37 : */ 38 : void enqueue(Runnable& runnable); 39 : 40 : private: 41 : void handleEvent(); 42 : 43 : Queue<Runnable> _queue; 44 : EventPolicy _eventPolicy; 45 : }; 46 : 47 : /** 48 : * Inline implementations. 49 : */ 50 : template<typename Runnable, typename EventPolicy, typename Lock> 51 194 : RunnableExecutor<Runnable, EventPolicy, Lock>::RunnableExecutor( 52 : typename EventPolicy::EventDispatcherType& eventDispatcher) 53 194 : : _queue(), _eventPolicy(eventDispatcher) 54 : {} 55 : 56 : template<typename Runnable, typename EventPolicy, typename Lock> 57 194 : void RunnableExecutor<Runnable, EventPolicy, Lock>::init() 58 : { 59 194 : _eventPolicy.setEventHandler( 60 : EventPolicy::HandlerFunctionType:: 61 : template create<RunnableExecutor, &RunnableExecutor::handleEvent>(*this)); 62 194 : } 63 : 64 : template<typename Runnable, typename EventPolicy, typename Lock> 65 1 : void RunnableExecutor<Runnable, EventPolicy, Lock>::shutdown() 66 : { 67 1 : _eventPolicy.removeEventHandler(); 68 : } 69 : 70 : template<typename Runnable, typename EventPolicy, typename Lock> 71 9 : inline void RunnableExecutor<Runnable, EventPolicy, Lock>::enqueue(Runnable& runnable) 72 : { 73 : { 74 5 : ESR_UNUSED const Lock lock; 75 9 : if (!runnable.isEnqueued()) 76 : { 77 17 : _queue.enqueue(runnable); 78 : } 79 5 : } 80 9 : _eventPolicy.setEvent(); 81 9 : } 82 : 83 : template<typename Runnable, typename EventPolicy, typename Lock> 84 5 : void RunnableExecutor<Runnable, EventPolicy, Lock>::handleEvent() 85 : { 86 6 : while (true) 87 : { 88 : Runnable* runnable; 89 : { 90 6 : ESR_UNUSED const Lock lock; 91 17 : runnable = _queue.dequeue(); 92 6 : } 93 6 : if (runnable != nullptr) 94 : { 95 6 : runnable->execute(); 96 : } 97 : else 98 : { 99 : break; 100 : } 101 : } 102 5 : } 103 : 104 : } // namespace async 105 : 106 : #endif // GUARD_ECCAA06F_729C_4CDD_9C3B_67D97352DE9E