The pipe used for signalling in the event queue was not properly cleared when popping events, causing the select() in the main loop to return immediately after the first event was queued, instead of blocking for the next event.