Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
unix: reactive new idle watcher implementation
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bnoordhuis committed May 22, 2012
1 parent 6190cab commit 80b5541
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 48 deletions.
1 change: 0 additions & 1 deletion include/uv-private/uv-unix.h
Expand Up @@ -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;

Expand Down
17 changes: 11 additions & 6 deletions src/unix/core.c
Expand Up @@ -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);
}

Expand Down
42 changes: 1 addition & 41 deletions src/unix/loop.c
Expand Up @@ -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);
}

0 comments on commit 80b5541

Please sign in to comment.