unix: reactive new idle watcher implementation
The new idle watcher was temporarily disabled in 073a48d due to some semantic
incompatibilities with the previous implementation. This commit resolves those
issues and reactivates the new implementation.
One outstanding bug is that idle watchers can run in a different order
(relative to other handle types) than the old implementation, e.g. (timer, idle)
instead of the expected (idle, timer). This will be fixed in an upcoming commit.
This commit is contained in:
parent
6190caba05
commit
80b554129b
@ -198,7 +198,6 @@ typedef struct {
|
||||
|
||||
/* UV_IDLE */
|
||||
#define UV_IDLE_PRIVATE_FIELDS \
|
||||
ev_idle idle_watcher; \
|
||||
uv_idle_cb idle_cb; \
|
||||
ngx_queue_t queue;
|
||||
|
||||
|
||||
@ -203,17 +203,22 @@ static void uv__poll(uv_loop_t* loop, int block) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__run(uv_loop_t* loop) {
|
||||
/*
|
||||
if (!uv__has_pending_handles(loop) && !uv__has_active_reqs(loop))
|
||||
uv__run_idle(loop);
|
||||
*/
|
||||
static int uv__should_block(uv_loop_t* loop) {
|
||||
return ngx_queue_empty(&loop->idle_handles)
|
||||
&& !ngx_queue_empty(&loop->active_handles);
|
||||
}
|
||||
|
||||
|
||||
static int uv__run(uv_loop_t* loop) {
|
||||
uv__run_idle(loop);
|
||||
uv__run_pending(loop);
|
||||
|
||||
if (uv__has_active_handles(loop) || uv__has_active_reqs(loop)) {
|
||||
uv__run_prepare(loop);
|
||||
uv__poll(loop, uv__has_active_handles(loop));
|
||||
/* Need to poll even if there are no active handles left, otherwise
|
||||
* uv_work_t reqs won't complete...
|
||||
*/
|
||||
uv__poll(loop, uv__should_block(loop));
|
||||
uv__run_check(loop);
|
||||
}
|
||||
|
||||
|
||||
@ -109,47 +109,7 @@ void uv__loop_delete(uv_loop_t* loop) {
|
||||
void uv__##name##_close(uv_##name##_t* handle) { \
|
||||
uv_##name##_stop(handle); \
|
||||
}
|
||||
/*X(idle, UV_IDLE)*/
|
||||
X(idle, UV_IDLE)
|
||||
X(check, UV_CHECK)
|
||||
X(prepare, UV_PREPARE)
|
||||
#undef X
|
||||
|
||||
|
||||
static void uv__idle(EV_P_ ev_idle* w, int revents) {
|
||||
uv_idle_t* handle = container_of(w, uv_idle_t, idle_watcher);
|
||||
handle->idle_cb(handle, 0);
|
||||
}
|
||||
|
||||
|
||||
int uv_idle_init(uv_loop_t* loop, uv_idle_t* handle) {
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_IDLE);
|
||||
ev_idle_init(&handle->idle_watcher, uv__idle);
|
||||
loop->counters.idle_init++;
|
||||
handle->idle_cb = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_idle_start(uv_idle_t* handle, uv_idle_cb cb) {
|
||||
if (uv__is_active(handle)) return 0;
|
||||
ngx_queue_insert_head(&handle->loop->idle_handles, &handle->queue);
|
||||
ev_idle_start(handle->loop->ev, &handle->idle_watcher);
|
||||
uv__handle_start(handle);
|
||||
handle->idle_cb = cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_idle_stop(uv_idle_t* handle) {
|
||||
if (!uv__is_active(handle)) return 0;
|
||||
ngx_queue_remove(&handle->queue);
|
||||
ev_idle_stop(handle->loop->ev, &handle->idle_watcher);
|
||||
uv__handle_stop(handle);
|
||||
handle->idle_cb = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__idle_close(uv_idle_t* handle) {
|
||||
uv_idle_stop(handle);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user