Note! This project has moved to github.com/armmbed/mbed-events

Dependents:   SimpleHTTPExample

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

Committer:
Christopher Haster
Date:
2016-04-18
Revision:
20:2f9d9c53a5af
Parent:
16:ff5d48fcce1b

File content as of revision 20:2f9d9c53a5af:

#include "EventLoop.h"
#include "rtos.h"


EventLoop::EventLoop(osPriority priority,
                     unsigned event_count,
                     unsigned event_context,
                     unsigned char *event_pointer,
                     uint32_t stack_size,
                     unsigned char *stack_pointer)
        : EventQueue(event_count, event_context, event_pointer) {
    _running = false;
    _priority = priority;
    _stack_size = stack_size;
    _stack_pointer = stack_pointer;
}

EventLoop::EventLoop(bool start,
                     osPriority priority,
                     unsigned event_count,
                     unsigned event_context,
                     unsigned char *event_pointer,
                     uint32_t stack_size,
                     unsigned char *stack_pointer)
        : EventQueue(event_count, event_context, event_pointer) {
    _running = false;
    _priority = priority;
    _stack_size = stack_size;
    _stack_pointer = stack_pointer;

    if (start) {
        EventLoop::start();
    }
}

EventLoop::~EventLoop() {
    stop();
}

osStatus EventLoop::start() {
    if (_running) {
        return osOK;
    }

    _running = true;
    _thread = new Thread(run, this, _priority, _stack_size, _stack_pointer);
    if (!_thread) {
        return osErrorNoMemory;
    }

    return osOK;
}

osStatus EventLoop::stop() {
    if (!_running) {
        return osOK;
    }

    Thread *thread = _thread;
    _thread = 0;

    _running = false;
    while (true) {
        uint8_t state = thread->get_state();
        if (state == Thread::Inactive || state == osErrorParameter) {
            break;
        }

        osStatus status = Thread::yield();
        if (status != osOK) {
            break;
        }
    }

    delete thread;
    return osOK;
}

void EventLoop::run(const void *p) {
    EventLoop *loop = (EventLoop *)p;

    while (loop->_running) {
        loop->dispatch(0);
        Thread::yield();
    }
}