| @@ -160,21 +160,29 @@ public: | |||
| EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout); | |||
| static void runFromYield() { | |||
| // First, check if yield was called from an interrupt | |||
| // never call normal handler functions from any interrupt context | |||
| uint32_t ipsr; | |||
| __asm__ volatile("mrs %0, ipsr\n" : "=r" (ipsr)::); | |||
| if (ipsr != 0) return; | |||
| // Next, check if any events have been triggered | |||
| EventResponder *first = firstYield; | |||
| // FIXME: also check if yield() called from an interrupt | |||
| // never run these functions from any interrupt context | |||
| if (first && !runningFromYield) { | |||
| runningFromYield = true; | |||
| firstYield = first->_next; | |||
| if (firstYield) { | |||
| firstYield->_prev = nullptr; | |||
| } else { | |||
| lastYield = nullptr; | |||
| } | |||
| first->_pending = false; | |||
| (*(first->_function))(*first); | |||
| runningFromYield = false; | |||
| if (first == nullptr) return; | |||
| // Finally, make sure we're not being recursively called, | |||
| // which can happen if the user's function does anything | |||
| // that calls yield. | |||
| if (runningFromYield) return; | |||
| // Ok, update the runningFromYield flag and process event | |||
| runningFromYield = true; | |||
| firstYield = first->_next; | |||
| if (firstYield) { | |||
| firstYield->_prev = nullptr; | |||
| } else { | |||
| lastYield = nullptr; | |||
| } | |||
| first->_pending = false; | |||
| (*(first->_function))(*first); | |||
| runningFromYield = false; | |||
| } | |||
| static void runFromInterrupt(); | |||
| operator bool() { return _pending; } | |||