#include "uv.h"
#include "task.h"
#include <string.h>
static
const
unsigned first_handle_number_idle = 2;
static
const
unsigned first_handle_number_prepare = 2;
static
const
unsigned first_handle_number_check = 2;
#ifdef __linux__
static
const
unsigned first_handle_number_fs_event = 0;
#endif
#define DEFINE_GLOBALS_AND_CBS(name) \
static
uv_##name##_t (name)[3]; \
static
unsigned name##_cb_calls[3]; \
\
static
void
name##2_cb(uv_##name##_t* handle) { \
ASSERT(handle == &(name)[2]); \
if
(first_handle_number_##name == 2) { \
uv_close((uv_handle_t*)&(name)[2], NULL); \
uv_close((uv_handle_t*)&(name)[1], NULL); \
} \
name##_cb_calls[2]++; \
} \
\
static
void
name##1_cb(uv_##name##_t* handle) { \
ASSERT(handle == &(name)[1]); \
ASSERT(0 &&
"Shouldn't be called"
&& (&name[0])); \
} \
\
static
void
name##0_cb(uv_##name##_t* handle) { \
ASSERT(handle == &(name)[0]); \
if
(first_handle_number_##name == 0) { \
uv_close((uv_handle_t*)&(name)[0], NULL); \
uv_close((uv_handle_t*)&(name)[1], NULL); \
} \
name##_cb_calls[0]++; \
} \
\
static
const
uv_##name##_cb name##_cbs[] = { \
(uv_##name##_cb)name##0_cb, \
(uv_##name##_cb)name##1_cb, \
(uv_##name##_cb)name##2_cb, \
};
#define INIT_AND_START(name, loop) \
do
{ \
size_t
i; \
for
(i = 0; i < ARRAY_SIZE(name); i++) { \
int
r; \
r = uv_##name##_init((loop), &(name)[i]); \
ASSERT(r == 0); \
\
r = uv_##name##_start(&(name)[i], name##_cbs[i]); \
ASSERT(r == 0); \
} \
}
while
(0)
#define END_ASSERTS(name) \
do
{ \
ASSERT(name##_cb_calls[0] == 1); \
ASSERT(name##_cb_calls[1] == 0); \
ASSERT(name##_cb_calls[2] == 1); \
}
while
(0)
DEFINE_GLOBALS_AND_CBS(idle)
DEFINE_GLOBALS_AND_CBS(prepare)
DEFINE_GLOBALS_AND_CBS(check)
#ifdef __linux__
DEFINE_GLOBALS_AND_CBS(fs_event)
static
const
char
watched_dir[] =
"."
;
static
uv_timer_t timer;
static
unsigned helper_timer_cb_calls;
static
void
init_and_start_fs_events(uv_loop_t* loop) {
size_t
i;
for
(i = 0; i < ARRAY_SIZE(fs_event); i++) {
int
r;
r = uv_fs_event_init(loop, &fs_event[i]);
ASSERT(r == 0);
r = uv_fs_event_start(&fs_event[i],
(uv_fs_event_cb)fs_event_cbs[i],
watched_dir,
0);
ASSERT(r == 0);
}
}
static
void
helper_timer_cb(uv_timer_t* thandle) {
int
r;
uv_fs_t fs_req;
r = uv_fs_utime(thandle->loop, &fs_req, watched_dir, 0, 0, NULL);
ASSERT(r == 0);
ASSERT(fs_req.result == 0);
ASSERT(fs_req.fs_type == UV_FS_UTIME);
ASSERT(
strcmp
(fs_req.path, watched_dir) == 0);
uv_fs_req_cleanup(&fs_req);
helper_timer_cb_calls++;
}
#endif
TEST_IMPL(queue_foreach_delete) {
uv_loop_t* loop;
int
r;
loop = uv_default_loop();
INIT_AND_START(idle, loop);
INIT_AND_START(prepare, loop);
INIT_AND_START(check, loop);
#ifdef __linux__
init_and_start_fs_events(loop);
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
r = uv_timer_start(&timer, helper_timer_cb, 0, 0);
ASSERT(r == 0);
#endif
r = uv_run(loop, UV_RUN_NOWAIT);
ASSERT(r == 1);
END_ASSERTS(idle);
END_ASSERTS(prepare);
END_ASSERTS(check);
#ifdef __linux__
ASSERT(helper_timer_cb_calls == 1);
#endif
MAKE_VALGRIND_HAPPY();
return
0;
}