Split up uv_loop type

This commit is contained in:
Bert Belder 2011-06-17 18:39:18 +02:00
parent debae03771
commit 4eb06151bd
14 changed files with 185 additions and 229 deletions

View File

@ -79,7 +79,7 @@ static double gbit(int64_t bytes, int64_t passed_ms) {
} }
static void show_stats(uv_handle_t *handle, int status) { static void show_stats(uv_timer_t* handle, int status) {
int64_t diff; int64_t diff;
#if PRINT_STATS #if PRINT_STATS

View File

@ -118,8 +118,8 @@ static void close_cb(uv_handle_t* handle) {
} }
static void async1_cb(uv_handle_t* handle, int status) { static void async1_cb(uv_async_t* handle, int status) {
ASSERT(handle == (uv_handle_t*)&async1_handle); ASSERT(handle == &async1_handle);
ASSERT(status == 0); ASSERT(status == 0);
async1_cb_called++; async1_cb_called++;
@ -127,7 +127,7 @@ static void async1_cb(uv_handle_t* handle, int status) {
if (async1_cb_called > 2 && !async1_closed) { if (async1_cb_called > 2 && !async1_closed) {
async1_closed = 1; async1_closed = 1;
uv_close(handle, close_cb); uv_close((uv_handle_t*)handle, close_cb);
} }
} }
@ -147,10 +147,10 @@ static void async2_cb(uv_handle_t* handle, int status) {
#endif #endif
static void prepare_cb(uv_handle_t* handle, int status) { static void prepare_cb(uv_prepare_t* handle, int status) {
int r; int r;
ASSERT(handle == (uv_handle_t*)&prepare_handle); ASSERT(handle == &prepare_handle);
ASSERT(status == 0); ASSERT(status == 0);
switch (prepare_cb_called) { switch (prepare_cb_called) {
@ -172,7 +172,7 @@ static void prepare_cb(uv_handle_t* handle, int status) {
#endif #endif
case 1: case 1:
r = uv_close(handle, close_cb); r = uv_close((uv_handle_t*)handle, close_cb);
ASSERT(r == 0); ASSERT(r == 0);
break; break;

View File

@ -109,10 +109,10 @@ static void read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
} }
static void timer_cb(uv_handle_t* handle, int status) { static void timer_cb(uv_timer_t* handle, int status) {
int r; int r;
ASSERT(handle == (uv_handle_t*)&timer); ASSERT(handle == &timer);
ASSERT(status == 0); ASSERT(status == 0);
ASSERT(nested == 0 && "timer_cb must be called from a fresh stack"); ASSERT(nested == 0 && "timer_cb must be called from a fresh stack");
@ -126,7 +126,7 @@ static void timer_cb(uv_handle_t* handle, int status) {
timer_cb_called++; timer_cb_called++;
r = uv_close(handle, close_cb); r = uv_close((uv_handle_t*)handle, close_cb);
ASSERT(r == 0); ASSERT(r == 0);
} }

View File

@ -46,7 +46,7 @@ static void timer_close_cb(uv_handle_t* handle) {
} }
static void timer_cb(uv_handle_t* handle, int status) { static void timer_cb(uv_timer_t* handle, int status) {
ASSERT(status == 0); ASSERT(status == 0);
timer_cb_calls++; timer_cb_calls++;
@ -62,7 +62,7 @@ static void timer_cb(uv_handle_t* handle, int status) {
uv_close((uv_handle_t*)&tcp, on_close); uv_close((uv_handle_t*)&tcp, on_close);
/* Close the timer. */ /* Close the timer. */
uv_close(handle, timer_close_cb); uv_close((uv_handle_t*)handle, timer_close_cb);
} }

View File

@ -49,7 +49,7 @@ static void close_cb(uv_handle_t* handle) {
} }
static void do_accept(uv_handle_t* timer_handle, int status) { static void do_accept(uv_timer_t* timer_handle, int status) {
uv_tcp_t* server; uv_tcp_t* server;
uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle); uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle);
int r; int r;
@ -83,7 +83,7 @@ static void do_accept(uv_handle_t* timer_handle, int status) {
} }
/* Dispose the timer. */ /* Dispose the timer. */
r = uv_close(timer_handle, close_cb); r = uv_close((uv_handle_t*)timer_handle, close_cb);
ASSERT(r == 0); ASSERT(r == 0);
} }

View File

@ -109,8 +109,8 @@ static int idle_2_is_active = 0;
static int timer_cb_called = 0; static int timer_cb_called = 0;
static void timer_cb(uv_handle_t* handle, int status) { static void timer_cb(uv_timer_t* handle, int status) {
ASSERT(handle == (uv_handle_t*)&timer_handle); ASSERT(handle == &timer_handle);
ASSERT(status == 0); ASSERT(status == 0);
timer_cb_called++; timer_cb_called++;
@ -129,22 +129,22 @@ static void idle_2_close_cb(uv_handle_t* handle) {
} }
static void idle_2_cb(uv_handle_t* handle, int status) { static void idle_2_cb(uv_idle_t* handle, int status) {
int r; int r;
LOG("IDLE_2_CB\n"); LOG("IDLE_2_CB\n");
ASSERT(handle == (uv_handle_t*)&idle_2_handle); ASSERT(handle == &idle_2_handle);
ASSERT(status == 0); ASSERT(status == 0);
idle_2_cb_called++; idle_2_cb_called++;
r = uv_close(handle, idle_2_close_cb); r = uv_close((uv_handle_t*)handle, idle_2_close_cb);
ASSERT(r == 0); ASSERT(r == 0);
} }
static void idle_1_cb(uv_handle_t* handle, int status) { static void idle_1_cb(uv_idle_t* handle, int status) {
int r; int r;
LOG("IDLE_1_CB\n"); LOG("IDLE_1_CB\n");
@ -207,12 +207,12 @@ static void prepare_2_close_cb(uv_handle_t* handle) {
} }
static void check_cb(uv_handle_t* handle, int status) { static void check_cb(uv_check_t* handle, int status) {
int i, r; int i, r;
LOG("CHECK_CB\n"); LOG("CHECK_CB\n");
ASSERT(handle == (uv_handle_t*)&check_handle); ASSERT(handle == &check_handle);
ASSERT(status == 0); ASSERT(status == 0);
/* XXX /* XXX
@ -254,12 +254,12 @@ static void check_cb(uv_handle_t* handle, int status) {
} }
static void prepare_2_cb(uv_handle_t* handle, int status) { static void prepare_2_cb(uv_prepare_t* handle, int status) {
int r; int r;
LOG("PREPARE_2_CB\n"); LOG("PREPARE_2_CB\n");
ASSERT(handle == (uv_handle_t*)&prepare_2_handle); ASSERT(handle == &prepare_2_handle);
ASSERT(status == 0); ASSERT(status == 0);
/* XXX ASSERT(idles_1_active == 0); */ /* XXX ASSERT(idles_1_active == 0); */
@ -278,12 +278,12 @@ static void prepare_2_cb(uv_handle_t* handle, int status) {
} }
static void prepare_1_cb(uv_handle_t* handle, int status) { static void prepare_1_cb(uv_prepare_t* handle, int status) {
int r; int r;
LOG("PREPARE_1_CB\n"); LOG("PREPARE_1_CB\n");
ASSERT(handle == (uv_handle_t*)&prepare_1_handle); ASSERT(handle == &prepare_1_handle);
ASSERT(status == 0); ASSERT(status == 0);
/* XXX /* XXX

View File

@ -120,9 +120,9 @@ void timer_close_cb(uv_handle_t* handle) {
} }
void timer_cb(uv_handle_t* handle, int status) { void timer_cb(uv_timer_t* handle, int status) {
ASSERT(handle == (uv_handle_t*) &timer); ASSERT(handle == &timer);
uv_close(handle, timer_close_cb); uv_close((uv_handle_t*) handle, timer_close_cb);
/* /*
* The most important assert of the test: we have not received * The most important assert of the test: we have not received

View File

@ -41,10 +41,10 @@ static void close_cb(uv_handle_t* handle) {
} }
static void repeat_1_cb(uv_handle_t* handle, int status) { static void repeat_1_cb(uv_timer_t* handle, int status) {
int r; int r;
ASSERT(handle == (uv_handle_t*)&repeat_1); ASSERT(handle == &repeat_1);
ASSERT(status == 0); ASSERT(status == 0);
ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50); ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50);
@ -57,7 +57,7 @@ static void repeat_1_cb(uv_handle_t* handle, int status) {
ASSERT(r == 0); ASSERT(r == 0);
if (uv_now() >= start_time + 500) { if (uv_now() >= start_time + 500) {
uv_close(handle, close_cb); uv_close((uv_handle_t*)handle, close_cb);
/* We're not calling uv_timer_again on repeat_2 any more, so after this */ /* We're not calling uv_timer_again on repeat_2 any more, so after this */
/* timer_2_cb is expected. */ /* timer_2_cb is expected. */
repeat_2_cb_allowed = 1; repeat_2_cb_allowed = 1;
@ -66,8 +66,8 @@ static void repeat_1_cb(uv_handle_t* handle, int status) {
} }
static void repeat_2_cb(uv_handle_t* handle, int status) { static void repeat_2_cb(uv_timer_t* handle, int status) {
ASSERT(handle == (uv_handle_t*) &repeat_2); ASSERT(handle == &repeat_2);
ASSERT(status == 0); ASSERT(status == 0);
ASSERT(repeat_2_cb_allowed); ASSERT(repeat_2_cb_allowed);
@ -76,8 +76,8 @@ static void repeat_2_cb(uv_handle_t* handle, int status) {
repeat_2_cb_called++; repeat_2_cb_called++;
if (uv_timer_get_repeat(&repeat_2) == 0) { if (uv_timer_get_repeat(&repeat_2) == 0) {
ASSERT(!uv_is_active(handle)); ASSERT(!uv_is_active((uv_handle_t*)handle));
uv_close(handle, close_cb); uv_close((uv_handle_t*)handle, close_cb);
return; return;
} }

View File

@ -42,7 +42,7 @@ static void once_close_cb(uv_handle_t* handle) {
} }
static void once_cb(uv_handle_t* handle, int status) { static void once_cb(uv_timer_t* handle, int status) {
printf("ONCE_CB %d\n", once_cb_called); printf("ONCE_CB %d\n", once_cb_called);
ASSERT(handle != NULL); ASSERT(handle != NULL);
@ -50,7 +50,7 @@ static void once_cb(uv_handle_t* handle, int status) {
once_cb_called++; once_cb_called++;
uv_close(handle, once_close_cb); uv_close((uv_handle_t*)handle, once_close_cb);
/* Just call this randomly for the code coverage. */ /* Just call this randomly for the code coverage. */
uv_update_time(); uv_update_time();
@ -66,7 +66,7 @@ static void repeat_close_cb(uv_handle_t* handle) {
} }
static void repeat_cb(uv_handle_t* handle, int status) { static void repeat_cb(uv_timer_t* handle, int status) {
printf("REPEAT_CB\n"); printf("REPEAT_CB\n");
ASSERT(handle != NULL); ASSERT(handle != NULL);
@ -75,12 +75,12 @@ static void repeat_cb(uv_handle_t* handle, int status) {
repeat_cb_called++; repeat_cb_called++;
if (repeat_cb_called == 5) { if (repeat_cb_called == 5) {
uv_close(handle, repeat_close_cb); uv_close((uv_handle_t*)handle, repeat_close_cb);
} }
} }
static void never_cb(uv_handle_t* handle, int status) { static void never_cb(uv_timer_t* handle, int status) {
FATAL("never_cb should never be called"); FATAL("never_cb should never be called");
} }

View File

@ -967,7 +967,7 @@ static void uv__prepare(EV_P_ ev_prepare* w, int revents) {
uv_prepare_t* prepare = w->data; uv_prepare_t* prepare = w->data;
if (prepare->prepare_cb) { if (prepare->prepare_cb) {
prepare->prepare_cb((uv_handle_t*)prepare, 0); prepare->prepare_cb(prepare, 0);
} }
} }
@ -985,7 +985,7 @@ int uv_prepare_init(uv_prepare_t* prepare) {
} }
int uv_prepare_start(uv_prepare_t* prepare, uv_loop_cb cb) { int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) {
int was_active = ev_is_active(&prepare->prepare_watcher); int was_active = ev_is_active(&prepare->prepare_watcher);
prepare->prepare_cb = cb; prepare->prepare_cb = cb;
@ -1017,7 +1017,7 @@ static void uv__check(EV_P_ ev_check* w, int revents) {
uv_check_t* check = w->data; uv_check_t* check = w->data;
if (check->check_cb) { if (check->check_cb) {
check->check_cb((uv_handle_t*)check, 0); check->check_cb(check, 0);
} }
} }
@ -1035,7 +1035,7 @@ int uv_check_init(uv_check_t* check) {
} }
int uv_check_start(uv_check_t* check, uv_loop_cb cb) { int uv_check_start(uv_check_t* check, uv_check_cb cb) {
int was_active = ev_is_active(&check->check_watcher); int was_active = ev_is_active(&check->check_watcher);
check->check_cb = cb; check->check_cb = cb;
@ -1067,7 +1067,7 @@ static void uv__idle(EV_P_ ev_idle* w, int revents) {
uv_idle_t* idle = (uv_idle_t*)(w->data); uv_idle_t* idle = (uv_idle_t*)(w->data);
if (idle->idle_cb) { if (idle->idle_cb) {
idle->idle_cb((uv_handle_t*)idle, 0); idle->idle_cb(idle, 0);
} }
} }
@ -1086,7 +1086,7 @@ int uv_idle_init(uv_idle_t* idle) {
} }
int uv_idle_start(uv_idle_t* idle, uv_loop_cb cb) { int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) {
int was_active = ev_is_active(&idle->idle_watcher); int was_active = ev_is_active(&idle->idle_watcher);
idle->idle_cb = cb; idle->idle_cb = cb;
@ -1137,7 +1137,7 @@ static void uv__async(EV_P_ ev_async* w, int revents) {
uv_async_t* async = w->data; uv_async_t* async = w->data;
if (async->async_cb) { if (async->async_cb) {
async->async_cb((uv_handle_t*)async, 0); async->async_cb(async, 0);
} }
} }
@ -1172,7 +1172,7 @@ static void uv__timer_cb(EV_P_ ev_timer* w, int revents) {
} }
if (timer->timer_cb) { if (timer->timer_cb) {
timer->timer_cb((uv_handle_t*)timer, 0); timer->timer_cb(timer, 0);
} }
} }
@ -1188,7 +1188,7 @@ int uv_timer_init(uv_timer_t* timer) {
} }
int uv_timer_start(uv_timer_t* timer, uv_loop_cb cb, int64_t timeout, int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
int64_t repeat) { int64_t repeat) {
if (ev_is_active(&timer->timer_watcher)) { if (ev_is_active(&timer->timer_watcher)) {
return -1; return -1;

View File

@ -70,31 +70,31 @@ typedef struct {
/* UV_PREPARE */ \ /* UV_PREPARE */ \
#define UV_PREPARE_PRIVATE_FIELDS \ #define UV_PREPARE_PRIVATE_FIELDS \
ev_prepare prepare_watcher; \ ev_prepare prepare_watcher; \
uv_loop_cb prepare_cb; uv_prepare_cb prepare_cb;
/* UV_CHECK */ /* UV_CHECK */
#define UV_CHECK_PRIVATE_FIELDS \ #define UV_CHECK_PRIVATE_FIELDS \
ev_check check_watcher; \ ev_check check_watcher; \
uv_loop_cb check_cb; uv_check_cb check_cb;
/* UV_IDLE */ /* UV_IDLE */
#define UV_IDLE_PRIVATE_FIELDS \ #define UV_IDLE_PRIVATE_FIELDS \
ev_idle idle_watcher; \ ev_idle idle_watcher; \
uv_loop_cb idle_cb; uv_idle_cb idle_cb;
/* UV_ASYNC */ /* UV_ASYNC */
#define UV_ASYNC_PRIVATE_FIELDS \ #define UV_ASYNC_PRIVATE_FIELDS \
ev_async async_watcher; \ ev_async async_watcher; \
uv_loop_cb async_cb; uv_async_cb async_cb;
/* UV_TIMER */ /* UV_TIMER */
#define UV_TIMER_PRIVATE_FIELDS \ #define UV_TIMER_PRIVATE_FIELDS \
ev_timer timer_watcher; \ ev_timer timer_watcher; \
uv_loop_cb timer_cb; uv_timer_cb timer_cb;
#endif /* UV_UNIX_H */ #endif /* UV_UNIX_H */

252
uv-win.c
View File

@ -149,17 +149,6 @@ RB_PROTOTYPE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare)
static struct uv_timer_tree_s uv_timers_ = RB_INITIALIZER(uv_timers_); static struct uv_timer_tree_s uv_timers_ = RB_INITIALIZER(uv_timers_);
/* Lists of active uv_prepare / uv_check / uv_idle watchers */
static uv_handle_t* uv_prepare_handles_ = NULL;
static uv_handle_t* uv_check_handles_ = NULL;
static uv_handle_t* uv_idle_handles_ = NULL;
/* This pointer will refer to the prepare/check/idle handle whose callback */
/* is scheduled to be called next. This is needed to allow safe removal */
/* from one of the lists above while that list being iterated. */
static uv_handle_t* uv_next_loop_handle_ = NULL;
/* Head of a single-linked list of closed handles */ /* Head of a single-linked list of closed handles */
static uv_handle_t* uv_endgame_handles_ = NULL; static uv_handle_t* uv_endgame_handles_ = NULL;
@ -569,7 +558,7 @@ static void uv_timer_endgame(uv_timer_t* handle) {
} }
static void uv_loop_endgame(uv_handle_t* handle) { static void uv_loop_watcher_endgame(uv_handle_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING) { if (handle->flags & UV_HANDLE_CLOSING) {
assert(!(handle->flags & UV_HANDLE_CLOSED)); assert(!(handle->flags & UV_HANDLE_CLOSED));
handle->flags |= UV_HANDLE_CLOSED; handle->flags |= UV_HANDLE_CLOSED;
@ -619,7 +608,7 @@ static void uv_process_endgames() {
case UV_PREPARE: case UV_PREPARE:
case UV_CHECK: case UV_CHECK:
case UV_IDLE: case UV_IDLE:
uv_loop_endgame(handle); uv_loop_watcher_endgame(handle);
break; break;
case UV_ASYNC: case UV_ASYNC:
@ -1258,7 +1247,7 @@ int uv_timer_init(uv_timer_t* handle) {
} }
int uv_timer_start(uv_timer_t* handle, uv_loop_cb timer_cb, int64_t timeout, int64_t repeat) { int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout, int64_t repeat) {
if (handle->flags & UV_HANDLE_ACTIVE) { if (handle->flags & UV_HANDLE_ACTIVE) {
RB_REMOVE(uv_timer_tree_s, &uv_timers_, handle); RB_REMOVE(uv_timer_tree_s, &uv_timers_, handle);
} }
@ -1341,140 +1330,103 @@ int64_t uv_now() {
} }
int uv_loop_init(uv_handle_t* handle) { #define UV_LOOP_WATCHER_DEFINE(name, NAME) \
handle->flags = 0; /* Lists of active loop (prepare / check / idle) watchers */ \
handle->error = uv_ok_; static uv_##name##_t* uv_##name##_handles_ = NULL; \
\
uv_refs_++; /* This pointer will refer to the prepare/check/idle handle whose */ \
/* callback is scheduled to be called next. This is needed to allow */ \
return 0; /* safe removal from one of the lists above while that list being */ \
} /* iterated over. */ \
static uv_##name##_t* uv_next_##name##_handle_ = NULL; \
\
static int uv_loop_start(uv_handle_t* handle, uv_loop_cb loop_cb, \
uv_handle_t** list) { int uv_##name##_init(uv_##name##_t* handle) { \
uv_handle_t* old_head; handle->type = UV_##NAME; \
handle->flags = 0; \
if (handle->flags & UV_HANDLE_ACTIVE) handle->error = uv_ok_; \
return 0; \
uv_refs_++; \
old_head = *list; \
uv_counters()->handle_init++; \
handle->loop_next = old_head; uv_counters()->prepare_init++; \
handle->loop_prev = NULL; \
return 0; \
if (old_head) { } \
old_head->loop_prev = handle; \
\
int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \
uv_##name##_t* old_head; \
\
assert(handle->type == UV_##NAME); \
\
if (handle->flags & UV_HANDLE_ACTIVE) \
return 0; \
\
old_head = uv_##name##_handles_; \
\
handle->name##_next = old_head; \
handle->name##_prev = NULL; \
\
if (old_head) { \
old_head->name##_prev = handle; \
} \
\
uv_##name##_handles_ = handle; \
\
handle->name##_cb = cb; \
handle->flags |= UV_HANDLE_ACTIVE; \
\
return 0; \
} \
\
\
int uv_##name##_stop(uv_##name##_t* handle) { \
assert(handle->type == UV_##NAME); \
\
if (!(handle->flags & UV_HANDLE_ACTIVE)) \
return 0; \
\
/* Update loop head if needed */ \
if (uv_##name##_handles_ == handle) { \
uv_##name##_handles_ = handle->name##_next; \
} \
\
/* Update the iterator-next pointer of needed */ \
if (uv_next_##name##_handle_ == handle) { \
uv_next_##name##_handle_ = handle->name##_next; \
} \
\
if (handle->name##_prev) { \
handle->name##_prev->name##_next = handle->name##_next; \
} \
if (handle->name##_next) { \
handle->name##_next->name##_prev = handle->name##_prev; \
} \
\
handle->flags &= ~UV_HANDLE_ACTIVE; \
\
return 0; \
} \
\
\
static void uv_##name##_invoke() { \
uv_##name##_t* handle; \
\
uv_next_##name##_handle_ = uv_##name##_handles_; \
\
while (uv_next_##name##_handle_ != NULL) { \
handle = uv_next_##name##_handle_; \
uv_next_##name##_handle_ = handle->name##_next; \
\
handle->name##_cb(handle, 0); \
} \
} }
*list = handle;
handle->loop_cb = loop_cb; UV_LOOP_WATCHER_DEFINE(prepare, PREPARE)
handle->flags |= UV_HANDLE_ACTIVE; UV_LOOP_WATCHER_DEFINE(check, CHECK)
UV_LOOP_WATCHER_DEFINE(idle, IDLE)
return 0;
}
static int uv_loop_stop(uv_handle_t* handle, uv_handle_t** list) {
if (!(handle->flags & UV_HANDLE_ACTIVE))
return 0;
/* Update loop head if needed */
if (*list == handle) {
*list = handle->loop_next;
}
/* Update the iterator-next pointer of needed */
if (uv_next_loop_handle_ == handle) {
uv_next_loop_handle_ = handle->loop_next;
}
if (handle->loop_prev) {
handle->loop_prev->loop_next = handle->loop_next;
}
if (handle->loop_next) {
handle->loop_next->loop_prev = handle->loop_prev;
}
handle->flags &= ~UV_HANDLE_ACTIVE;
return 0;
}
static void uv_loop_invoke(uv_handle_t* list) {
uv_handle_t *handle;
uv_next_loop_handle_ = list;
while (uv_next_loop_handle_ != NULL) {
handle = uv_next_loop_handle_;
uv_next_loop_handle_ = handle->loop_next;
handle->loop_cb(handle, 0);
}
}
int uv_prepare_init(uv_prepare_t* handle) {
uv_counters()->handle_init++;
uv_counters()->prepare_init++;
handle->type = UV_PREPARE;
return uv_loop_init((uv_handle_t*)handle);
}
int uv_check_init(uv_check_t* handle) {
uv_counters()->handle_init++;
uv_counters()->check_init++;
handle->type = UV_CHECK;
return uv_loop_init((uv_handle_t*)handle);
}
int uv_idle_init(uv_idle_t* handle) {
uv_counters()->handle_init++;
uv_counters()->idle_init++;
handle->type = UV_IDLE;
return uv_loop_init((uv_handle_t*)handle);
}
int uv_prepare_start(uv_prepare_t* handle, uv_loop_cb loop_cb) {
assert(handle->type == UV_PREPARE);
return uv_loop_start((uv_handle_t*)handle, loop_cb, &uv_prepare_handles_);
}
int uv_check_start(uv_check_t* handle, uv_loop_cb loop_cb) {
assert(handle->type == UV_CHECK);
return uv_loop_start((uv_handle_t*)handle, loop_cb, &uv_check_handles_);
}
int uv_idle_start(uv_idle_t* handle, uv_loop_cb loop_cb) {
assert(handle->type == UV_IDLE);
return uv_loop_start((uv_handle_t*)handle, loop_cb, &uv_idle_handles_);
}
int uv_prepare_stop(uv_prepare_t* handle) {
assert(handle->type == UV_PREPARE);
return uv_loop_stop((uv_handle_t*)handle, &uv_prepare_handles_);
}
int uv_check_stop(uv_check_t* handle) {
assert(handle->type == UV_CHECK);
return uv_loop_stop((uv_handle_t*)handle, &uv_check_handles_);
}
int uv_idle_stop(uv_idle_t* handle) {
assert(handle->type == UV_IDLE);
return uv_loop_stop((uv_handle_t*)handle, &uv_idle_handles_);
}
int uv_is_active(uv_handle_t* handle) { int uv_is_active(uv_handle_t* handle) {
@ -1541,7 +1493,7 @@ static void uv_async_return_req(uv_async_t* handle, uv_req_t* req) {
handle->async_sent = 0; handle->async_sent = 0;
if (req->cb) { if (req->cb) {
((uv_async_cb)req->cb)((uv_handle_t*)handle, 0); ((uv_async_cb)req->cb)((uv_async_t*) handle, 0);
} }
if (handle->flags & UV_HANDLE_CLOSING) { if (handle->flags & UV_HANDLE_CLOSING) {
uv_want_endgame((uv_handle_t*)handle); uv_want_endgame((uv_handle_t*)handle);
@ -1595,7 +1547,7 @@ static void uv_process_timers() {
timer->flags &= ~UV_HANDLE_ACTIVE; timer->flags &= ~UV_HANDLE_ACTIVE;
} }
timer->timer_cb((uv_handle_t*) timer, 0); timer->timer_cb((uv_timer_t*) timer, 0);
} }
} }
@ -1676,18 +1628,18 @@ int uv_run() {
} }
/* Call idle callbacks */ /* Call idle callbacks */
uv_loop_invoke(uv_idle_handles_); uv_idle_invoke();
} }
if (uv_refs_ <= 0) { if (uv_refs_ <= 0) {
break; break;
} }
uv_loop_invoke(uv_prepare_handles_); uv_prepare_invoke();
uv_poll(); uv_poll();
uv_loop_invoke(uv_check_handles_); uv_check_invoke();
} }
assert(uv_refs_ == 0); assert(uv_refs_ == 0);

View File

@ -81,32 +81,32 @@ typedef struct uv_buf_t {
RB_ENTRY(uv_timer_s) tree_entry; \ RB_ENTRY(uv_timer_s) tree_entry; \
int64_t due; \ int64_t due; \
int64_t repeat; \ int64_t repeat; \
uv_loop_cb timer_cb; uv_timer_cb timer_cb;
#define UV_LOOP_PRIVATE_FIELDS \
uv_handle_t* loop_prev; \
uv_handle_t* loop_next; \
uv_loop_cb loop_cb;
#define UV_ASYNC_PRIVATE_FIELDS \ #define UV_ASYNC_PRIVATE_FIELDS \
struct uv_req_s async_req; \ struct uv_req_s async_req; \
/* char to avoid alignment issues */ \ /* char to avoid alignment issues */ \
char volatile async_sent; char volatile async_sent;
#define UV_PREPARE_PRIVATE_FIELDS /* empty */ #define UV_PREPARE_PRIVATE_FIELDS \
#define UV_CHECK_PRIVATE_FIELDS /* empty */ uv_prepare_t* prepare_prev; \
#define UV_IDLE_PRIVATE_FIELDS /* empty */ uv_prepare_t* prepare_next; \
uv_prepare_cb prepare_cb;
/* #define UV_CHECK_PRIVATE_FIELDS \
* TODO: remove UV_LOOP_PRIVATE_FIELDS from UV_HANDLE_PRIVATE_FIELDS and uv_check_t* check_prev; \
* use it in UV_(PREPARE|CHECK|IDLE)_PRIVATE_FIELDS instead. uv_check_t* check_next; \
*/ uv_check_cb check_cb;
#define UV_IDLE_PRIVATE_FIELDS \
uv_idle_t* idle_prev; \
uv_idle_t* idle_next; \
uv_idle_cb idle_cb;
#define UV_HANDLE_PRIVATE_FIELDS \ #define UV_HANDLE_PRIVATE_FIELDS \
uv_handle_t* endgame_next; \ uv_handle_t* endgame_next; \
unsigned int flags; \ unsigned int flags; \
uv_err_t error; \ uv_err_t error;
UV_LOOP_PRIVATE_FIELDS
int uv_utf16_to_utf8(wchar_t* utf16Buffer, size_t utf16Size, char* utf8Buffer, size_t utf8Size); int uv_utf16_to_utf8(wchar_t* utf16Buffer, size_t utf16Size, char* utf8Buffer, size_t utf8Size);

22
uv.h
View File

@ -47,6 +47,7 @@ typedef struct uv_prepare_s uv_prepare_t;
typedef struct uv_check_s uv_check_t; typedef struct uv_check_s uv_check_t;
typedef struct uv_idle_s uv_idle_t; typedef struct uv_idle_s uv_idle_t;
typedef struct uv_req_s uv_req_t; typedef struct uv_req_s uv_req_t;
typedef struct uv_async_s uv_async_t;
#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__) #if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
@ -71,9 +72,12 @@ typedef void (*uv_connect_cb)(uv_req_t* req, int status);
typedef void (*uv_shutdown_cb)(uv_req_t* req, int status); typedef void (*uv_shutdown_cb)(uv_req_t* req, int status);
typedef void (*uv_connection_cb)(uv_tcp_t* server, int status); typedef void (*uv_connection_cb)(uv_tcp_t* server, int status);
typedef void (*uv_close_cb)(uv_handle_t* handle); typedef void (*uv_close_cb)(uv_handle_t* handle);
/* TODO: do loop_cb and async_cb really need a status argument? */ typedef void (*uv_timer_cb)(uv_timer_t* handle, int status);
typedef void (*uv_loop_cb)(uv_handle_t* handle, int status); /* TODO: do these really need a status argument? */
typedef void (*uv_async_cb)(uv_handle_t* handle, int status); typedef void (*uv_async_cb)(uv_async_t* handle, int status);
typedef void (*uv_prepare_cb)(uv_prepare_t* handle, int status);
typedef void (*uv_check_cb)(uv_check_t* handle, int status);
typedef void (*uv_idle_cb)(uv_idle_t* handle, int status);
/* Expand this list if necessary. */ /* Expand this list if necessary. */
@ -269,7 +273,7 @@ struct uv_prepare_s {
int uv_prepare_init(uv_prepare_t* prepare); int uv_prepare_init(uv_prepare_t* prepare);
int uv_prepare_start(uv_prepare_t* prepare, uv_loop_cb cb); int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
int uv_prepare_stop(uv_prepare_t* prepare); int uv_prepare_stop(uv_prepare_t* prepare);
@ -286,7 +290,7 @@ struct uv_check_s {
int uv_check_init(uv_check_t* check); int uv_check_init(uv_check_t* check);
int uv_check_start(uv_check_t* check, uv_loop_cb cb); int uv_check_start(uv_check_t* check, uv_check_cb cb);
int uv_check_stop(uv_check_t* check); int uv_check_stop(uv_check_t* check);
@ -304,7 +308,7 @@ struct uv_idle_s {
int uv_idle_init(uv_idle_t* idle); int uv_idle_init(uv_idle_t* idle);
int uv_idle_start(uv_idle_t* idle, uv_loop_cb cb); int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb);
int uv_idle_stop(uv_idle_t* idle); int uv_idle_stop(uv_idle_t* idle);
@ -317,10 +321,10 @@ int uv_idle_stop(uv_idle_t* idle);
* after the call to async_send. Unlike all other libuv functions, * after the call to async_send. Unlike all other libuv functions,
* uv_async_send can be called from another thread. * uv_async_send can be called from another thread.
*/ */
typedef struct { struct uv_async_s {
UV_HANDLE_FIELDS UV_HANDLE_FIELDS
UV_ASYNC_PRIVATE_FIELDS UV_ASYNC_PRIVATE_FIELDS
} uv_async_t; };
int uv_async_init(uv_async_t* async, uv_async_cb async_cb); int uv_async_init(uv_async_t* async, uv_async_cb async_cb);
@ -338,7 +342,7 @@ struct uv_timer_s {
int uv_timer_init(uv_timer_t* timer); int uv_timer_init(uv_timer_t* timer);
int uv_timer_start(uv_timer_t* timer, uv_loop_cb cb, int64_t timeout, int64_t repeat); int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout, int64_t repeat);
int uv_timer_stop(uv_timer_t* timer); int uv_timer_stop(uv_timer_t* timer);