- Remove the UV_HANDLE_ACTIVE flag. It's a duplicate from
UV__HANDLE_ACTIVE, which was used solely on timers and loop watchers.
- Avoid duplicated code when running timers by stopping the handle and
rearming it with the repeat time, thus having a single place where the
timers are added and removed to and from the RB tree, respectively.
This commit changes the libuv API to return error codes directly rather
than storing them in a loop-global field.
A code snippet like this one:
if (uv_foo(loop) < 0) {
uv_err_t err = uv_last_error(loop);
fprintf(stderr, "%s\n", uv_strerror(err));
}
Should be rewritten like this:
int err = uv_foo(loop);
if (err < 0)
fprintf(stderr, "%s\n", uv_strerror(err));
The rationale for this change is that it should make creating bindings
for other languages a lot easier: dealing with struct return values is
painful with most FFIs and often downright buggy.
We use GetQueuedCompletionStatus(Ex) to sleep the thread until the next
timer expires (provided that no other events happen before that).
However after waking up from a sleep the GetTickCount() return value may
not immediately reflect that some time has passed. This happens because
gqcs can sometimes sleep for periods shorter than the GetTickCount clock
resulution. This patch changes time tracking so the amount of time
waited by gqcs is taken into account.
This has the following advantages:
* Excessive loop iterations are avoided.
* Small timeouts are fired more precisely.
* The `loop-stop` test that used to be flaky on Windows now passes
consistently.
This commit changes how the event loop determines if it needs to stay alive.
Previously, an internal counter was increased whenever a handle got created
and decreased again when the handle was closed.
While conceptually simple, it turned out hard to work with: you often want
to keep the event loop alive only if the handle is actually doing something.
Stopped or inactive handles were a frequent source of hanging event loops.
That's why this commit changes the reference counting scheme to a model where
a handle only references the event loop when it's active. 'Active' means
different things for different handle types, e.g.:
* timers: ticking
* sockets: reading, writing or listening
* processes: always active (for now, subject to change)
* idle, check, prepare: only active when started
This commit also changes how the uv_ref() and uv_unref() functions work: they
now operate on the level of individual handles, not the whole event loop.
The Windows implementation was done by Bert Belder.