TL;DR
What is the best implementation for an event loop in C/C++ that manages the call stack well?
- Why?
- Benchmarks/Comparisons?
- Literature/Publications/Documentation?
Event Loops, the Problem
They're an easy concept: Wait for an event, handle event, wait for more events.
I was looking back over some old projects and came across a simple (and kinda poor) implementation of a search engine, and my curiosity was sparked about the proper way to do event loops.
At the time I'd done something like this (very) simplified example:
int wait_for_query();
int handle_query();
int main(int argc, const char** argv) {
return wait_for_query();
}
int wait_for_query() {
// Do some stuff
return handle_query();
}
int handle_query() {
// Handle it
// if query is quit, return quit();
return wait_for_query();
}
int quit() {
return 0;
}
This implementation relies on call-chaining to achieve an "event loop". I use quotes because while it's logically an event loop, the call stack continually increases and never unwinds:
wait_for_query____...
/
handle_query_______/
/
wait_for_query_______/
While it works, it's always adding new stack frames onto the stack and eventually, after enough events, it will cause a Stack Overflow error! (haha so meta).
What I want is something like this:
handle_query handle_query
/ \ / \
wait_for_query_______/ \_______/ \_____...
What I've got so far
I've always heard that an OS is just a while(true)
loop that gets interrupted, so (since my OS hasn't gotten a SO error recently) here's what I thought would be good:
Replace main with:
while(1) if (wait_for_query() == 0) break; return 0;
- Change
handle_query
's return to 1
But does this actually make it more stack efficient? To my knowledge, while
loops (and loops in general) still produce stack frames in assembly language (since they're all branches in execution with scope/local variables/etc.)
What is the best implementation for an event loop in C/C++ that manages the call stack well?
- Why?
- Benchmarks/Comparisons?
- Literature/Publications/Documentation?
Notes
This question assumes a single threaded event loop. Parallelized answers are acceptable too, but I thought that'd would be a bit much to ask about all at once ;)
Fire away