Note! This project has moved to github.com/armmbed/mbed-events
This repository has been superceded
This project has moved to mbed-events
Composable event loops combine the cheap synchronicity of event loops with the composability of preempted threads.
Two modular event queue classes are provided:
- EventLoop - for loops coupled with a c++ managed thread
- EventQueue - for manually managed event queues
The Event class takes advantage of the extensibility of FuncPtr to allow an event to be passed through APIs as a normal function.
More information on composable event loops.
EventLoop.cpp@14:5abf2ccf2dbf, 2016-05-10 (annotated)
- Committer:
- Christopher Haster
- Date:
- Tue May 10 07:51:44 2016 -0500
- Revision:
- 14:5abf2ccf2dbf
- Parent:
- 8:3c2a014bd907
- Child:
- 16:ff5d48fcce1b
Move to internal memory management
Allows an event to be enqueued multiple times before being handled.
Downside is cancel is non-trivial to support.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Christopher Haster |
8:3c2a014bd907 | 1 | #include "EventLoop.h" |
Christopher Haster |
8:3c2a014bd907 | 2 | |
Christopher Haster |
8:3c2a014bd907 | 3 | #ifndef EVENTS_NO_RTOS |
Christopher Haster |
8:3c2a014bd907 | 4 | |
Christopher Haster |
8:3c2a014bd907 | 5 | using namespace rtos; |
Christopher Haster |
8:3c2a014bd907 | 6 | |
Christopher Haster |
14:5abf2ccf2dbf | 7 | EventLoop::EventLoop(osPriority priority, |
Christopher Haster |
14:5abf2ccf2dbf | 8 | unsigned event_count, |
Christopher Haster |
14:5abf2ccf2dbf | 9 | unsigned event_context, |
Christopher Haster |
14:5abf2ccf2dbf | 10 | uint32_t stack_size, |
Christopher Haster |
14:5abf2ccf2dbf | 11 | unsigned char *stack_pointer) |
Christopher Haster |
14:5abf2ccf2dbf | 12 | : EventQueue(event_count, event_context) { |
Christopher Haster |
8:3c2a014bd907 | 13 | _running = false; |
Christopher Haster |
14:5abf2ccf2dbf | 14 | _priority = priority; |
Christopher Haster |
14:5abf2ccf2dbf | 15 | _stack_size = stack_size; |
Christopher Haster |
14:5abf2ccf2dbf | 16 | _stack_pointer = stack_pointer; |
Christopher Haster |
8:3c2a014bd907 | 17 | } |
Christopher Haster |
8:3c2a014bd907 | 18 | |
Christopher Haster |
8:3c2a014bd907 | 19 | EventLoop::EventLoop(bool start, |
Christopher Haster |
8:3c2a014bd907 | 20 | osPriority priority, |
Christopher Haster |
14:5abf2ccf2dbf | 21 | unsigned event_count, |
Christopher Haster |
14:5abf2ccf2dbf | 22 | unsigned event_context, |
Christopher Haster |
8:3c2a014bd907 | 23 | uint32_t stack_size, |
Christopher Haster |
14:5abf2ccf2dbf | 24 | unsigned char *stack_pointer) |
Christopher Haster |
14:5abf2ccf2dbf | 25 | : EventQueue(event_count, event_context) { |
Christopher Haster |
8:3c2a014bd907 | 26 | _running = false; |
Christopher Haster |
14:5abf2ccf2dbf | 27 | _priority = priority; |
Christopher Haster |
14:5abf2ccf2dbf | 28 | _stack_size = stack_size; |
Christopher Haster |
14:5abf2ccf2dbf | 29 | _stack_pointer = stack_pointer; |
Christopher Haster |
8:3c2a014bd907 | 30 | |
Christopher Haster |
8:3c2a014bd907 | 31 | if (start) { |
Christopher Haster |
14:5abf2ccf2dbf | 32 | EventLoop::start(); |
Christopher Haster |
8:3c2a014bd907 | 33 | } |
Christopher Haster |
8:3c2a014bd907 | 34 | } |
Christopher Haster |
8:3c2a014bd907 | 35 | |
Christopher Haster |
8:3c2a014bd907 | 36 | EventLoop::~EventLoop() { |
Christopher Haster |
8:3c2a014bd907 | 37 | stop(); |
Christopher Haster |
8:3c2a014bd907 | 38 | } |
Christopher Haster |
8:3c2a014bd907 | 39 | |
Christopher Haster |
14:5abf2ccf2dbf | 40 | void EventLoop::start() { |
Christopher Haster |
8:3c2a014bd907 | 41 | if (_running) { |
Christopher Haster |
8:3c2a014bd907 | 42 | return; |
Christopher Haster |
8:3c2a014bd907 | 43 | } |
Christopher Haster |
8:3c2a014bd907 | 44 | |
Christopher Haster |
8:3c2a014bd907 | 45 | _running = true; |
Christopher Haster |
14:5abf2ccf2dbf | 46 | _thread = new Thread(run, this, _priority, _stack_size, _stack_pointer); |
Christopher Haster |
8:3c2a014bd907 | 47 | } |
Christopher Haster |
8:3c2a014bd907 | 48 | |
Christopher Haster |
8:3c2a014bd907 | 49 | void EventLoop::stop() { |
Christopher Haster |
8:3c2a014bd907 | 50 | if (!_running) { |
Christopher Haster |
8:3c2a014bd907 | 51 | return; |
Christopher Haster |
8:3c2a014bd907 | 52 | } |
Christopher Haster |
8:3c2a014bd907 | 53 | |
Christopher Haster |
8:3c2a014bd907 | 54 | Thread *thread = _thread; |
Christopher Haster |
8:3c2a014bd907 | 55 | _thread = 0; |
Christopher Haster |
8:3c2a014bd907 | 56 | |
Christopher Haster |
8:3c2a014bd907 | 57 | _running = false; |
Christopher Haster |
8:3c2a014bd907 | 58 | while (thread->get_state() != Thread::Inactive) { |
Christopher Haster |
8:3c2a014bd907 | 59 | Thread::yield(); |
Christopher Haster |
8:3c2a014bd907 | 60 | } |
Christopher Haster |
8:3c2a014bd907 | 61 | |
Christopher Haster |
8:3c2a014bd907 | 62 | delete thread; |
Christopher Haster |
8:3c2a014bd907 | 63 | } |
Christopher Haster |
8:3c2a014bd907 | 64 | |
Christopher Haster |
8:3c2a014bd907 | 65 | void EventLoop::run(const void *p) { |
Christopher Haster |
8:3c2a014bd907 | 66 | EventLoop *loop = (EventLoop *)p; |
Christopher Haster |
8:3c2a014bd907 | 67 | |
Christopher Haster |
8:3c2a014bd907 | 68 | while (loop->_running) { |
Christopher Haster |
8:3c2a014bd907 | 69 | loop->dispatch(0); |
Christopher Haster |
8:3c2a014bd907 | 70 | Thread::yield(); |
Christopher Haster |
8:3c2a014bd907 | 71 | } |
Christopher Haster |
8:3c2a014bd907 | 72 | } |
Christopher Haster |
8:3c2a014bd907 | 73 | |
Christopher Haster |
8:3c2a014bd907 | 74 | #endif |