Debug build failed on mingw32 because CRT assertion disable code was stubbed out.
Replace __declspec(thread) with UV_THREAD_LOCAL which is defined as __thread on GCC.
These functions supersede uv_loop_new and uv_loop_delete.
uv_loop_init initialized a user allocated loop and uv_loop_close
removes all associated resources a loop uses after it has finished
execution.
uv_loop_new and uv_loop_delete are now deprecated.
The crtdbg.h header was added in c0716b3d, but MinGW does not have this
header present on the system. This commit takes the same approach of
2684f876a and just ignores this header and functionality on MinGW
If passed and invalid FD, _get_osfhandle() sets an error code
through errno, not _doserrno. Hence we need to use
SET_REQ_WIN32_ERROR insted of SET_REQ_RESULT.
In debug builds, _get_osfhandle() also raises a superfluous
assert. I implemented a wrapper that disables all asserts
around the call to _get_osfhandle().
This fixes node.js unit tests test-fs-read-stream.js and
test-listen-fd-ebadf.js.
Useful to know when the the event loop is empty, this can't be done with
uv_run() without possibly blocking, or running some events (which might
empty the event loop as a side-effect).
Cheking if the loop is alive is covered in the while loop afterwards.
Also, the stop flag will be cleared if necessary, which didn't happen
before this patch.
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.
Before this commit, creating an event loop, starting a timer and
calling uv_run(UV_RUN_ONCE) blocked in uv_run() until the timer
expired - but didn't actually run the timer.
This mimicks what the unix implementation does: call idle handles on
every loop iteration. The guarantee that it runs on every loop iteration
makes it easier to predict and opens up more use cases.
Note that the name uv_idle is now a bit of a misnomer. There is
actually no guarantee that libuv completely processed all i/o
when an iteration ends. The windows implementation at least limits
the amount of callbacks processed in a single iteration to avoid some
handles getting a disproportionate amount of cpu attention.
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.
The default loop lives in the bss section so it's zeroed on startup
but loops created with uv_loop_new() live on the heap and contain
random garbage. Initialize the stop_flag explicitly to avoid spurious
bugs.
This changes the prototype of uv_run() from:
int uv_run(uv_loop_t* loop);
To:
int uv_run(uv_loop_t* loop, uv_run_mode mode);
Where `mode` is UV_RUN_DEFAULT, UV_RUN_ONCE or UV_RUN_NOWAIT.
Fixes#683.
Allows for running the event loop in 3 modes:
* default: loop runs until the refcount drops to zero
* once: poll for events only once and block until one is handled
* nowait: poll for events only once but don't block if there are
no pending events
This can be used in conjuction with uv_run_once() to poll in one thread and run
the event loop's event callbacks in another.
Useful for embedding libuv's event loop in another event loop.
uv_update_time does not overwrite the high 32 bits of uv_loop_t.time.
It merely increments it by one when the low 32 bits have wrapped. That
means that `time` needs to be initialized to zero before
uv_update_time() is called for the first time.
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.