Tell me please, here is a quote from reference section 3 ("Running an event loop") of Nick Mathewson's book on Libevent:
By default, the event_base_loop() function runs an event_base until there are no more events registered in it.
Honestly, I just can't understand this phrase.
What means - "until there are no more events registered".
How does a loop know that there are no more new events ?? There can be a time interval between events - 1 second, 1 hour ...
How does Libevent know that events are over?
PS: I'm trying to compare the work of the event_base_loop () function with the GetQueuedCompletionStatus () function on windows and I don't get it. Because GetQueuedCompletionStatus works in an infinite loop - whether there are events or not - GetQueuedCompletionStatus waits for an infinitely new event and does not complete if there are none.
PS1:I was in a hurry and did not finish the chapter on "Working with an event loop".
It says that you can redefine the behavior of the event_base_loop () function by passing it a flag in the second parameter - EVLOOP_NO_EXIT_ON_EMPTY.
This will mean that the function will wait for new events indefinitely or until I want to exit the event_base_loop () loop manually via event_base_loopbreak / event_base_loopexit.
Note it says "no more events registered", rather than "no more events". By default, the event loop will exit when the event base runs empty, even though more events could happen later. This is restated in a different way both later in the chapter:
Ordinarily, the loop will exit as soon as it has no pending or active events.
and in the API documentation for event_base_loop():
By default, this loop will run the event base until either there are no more pending or active events, or until something calls event_base_loopbreak() or event_base_loopexit().
As noted in the question, EVLOOP_NO_EXIT_ON_EMPTY can change this behavior to work more like a typical event queue, waiting for events (unless EVLOOP_NONBLOCK was set) and dispatching them when they arrive.
"Running an event loop" contains pseudocode for event_base_loop() that should also help clarify the behavior.
In comparison, GetQueuedCompletionStatus will wait for and operate on a single packet (note: the wait is not likely a busyloop but based on some other multitasking technologies, such as interrupts and thread synchronization primitives; the exact method is an implementation detail, and shouldn't affect use). It's most similar to event_base_loop() with the flags EVLOOP_ONCE | EVLOOP_NO_EXIT_ON_EMPTY, though event_base_loop may process multiple events of the same priority if they happen to come in before the first event is fully handled. Coming from the other direction, if 0 is passed for the dwMilliseconds argument to GetQueuedCompletionStatus, it behaves like event_base_loop()'s default behavior, exiting immediately if there are no packets in the I/O completion queue.