static int uv__loop_init(uv_loop_t* loop, int default_loop) { unsigned int i; int err; uv__signal_global_once_init(); memset(loop, 0, sizeof(*loop)); RB_INIT(&loop->timer_handles); QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->active_reqs); QUEUE_INIT(&loop->idle_handles); QUEUE_INIT(&loop->async_handles); QUEUE_INIT(&loop->check_handles); QUEUE_INIT(&loop->prepare_handles); QUEUE_INIT(&loop->handle_queue); loop->nfds = 0; loop->watchers = NULL; loop->nwatchers = 0; QUEUE_INIT(&loop->pending_queue); QUEUE_INIT(&loop->watcher_queue); loop->closing_handles = NULL; loop->time = uv__hrtime() / 1000000; uv__async_init(&loop->async_watcher); loop->signal_pipefd[0] = -1; loop->signal_pipefd[1] = -1; loop->backend_fd = -1; loop->emfile_fd = -1; loop->timer_counter = 0; loop->stop_flag = 0; err = uv__platform_loop_init(loop, default_loop); if (err) return err; uv_signal_init(loop, &loop->child_watcher); uv__handle_unref(&loop->child_watcher); loop->child_watcher.flags |= UV__HANDLE_INTERNAL; for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) QUEUE_INIT(loop->process_handles + i); if (uv_mutex_init(&loop->wq_mutex)) abort(); if (uv_async_init(loop, &loop->wq_async, uv__work_done)) abort(); uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV__HANDLE_INTERNAL; return 0; }
int uv_loop_init(uv_loop_t* loop) { int err; uv__signal_global_once_init(); memset(loop, 0, sizeof(*loop)); heap_init((struct heap*) &loop->timer_heap); QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->active_reqs); QUEUE_INIT(&loop->idle_handles); QUEUE_INIT(&loop->async_handles); QUEUE_INIT(&loop->check_handles); QUEUE_INIT(&loop->prepare_handles); QUEUE_INIT(&loop->handle_queue); loop->nfds = 0; loop->watchers = NULL; loop->nwatchers = 0; QUEUE_INIT(&loop->pending_queue); QUEUE_INIT(&loop->watcher_queue); loop->closing_handles = NULL; uv__update_time(loop); uv__async_init(&loop->async_watcher); loop->signal_pipefd[0] = -1; loop->signal_pipefd[1] = -1; loop->backend_fd = -1; loop->emfile_fd = -1; loop->timer_counter = 0; loop->stop_flag = 0; err = uv__platform_loop_init(loop); if (err) return err; uv_signal_init(loop, &loop->child_watcher); uv__handle_unref(&loop->child_watcher); loop->child_watcher.flags |= UV__HANDLE_INTERNAL; QUEUE_INIT(&loop->process_handles); if (uv_rwlock_init(&loop->cloexec_lock)) abort(); if (uv_mutex_init(&loop->wq_mutex)) abort(); if (uv_async_init(loop, &loop->wq_async, uv__work_done)) abort(); uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV__HANDLE_INTERNAL; return 0; }
int uv__loop_init(uv_loop_t* loop, int default_loop) { unsigned int i; int flags; uv__signal_global_once_init(); #if HAVE_KQUEUE flags = EVBACKEND_KQUEUE; #else flags = EVFLAG_AUTO; #endif memset(loop, 0, sizeof(*loop)); RB_INIT(&loop->timer_handles); ngx_queue_init(&loop->wq); ngx_queue_init(&loop->active_reqs); ngx_queue_init(&loop->idle_handles); ngx_queue_init(&loop->async_handles); ngx_queue_init(&loop->check_handles); ngx_queue_init(&loop->prepare_handles); ngx_queue_init(&loop->handle_queue); loop->closing_handles = NULL; loop->time = uv_hrtime() / 1000000; loop->async_pipefd[0] = -1; loop->async_pipefd[1] = -1; loop->async_sweep_needed = 0; loop->signal_pipefd[0] = -1; loop->signal_pipefd[1] = -1; loop->emfile_fd = -1; loop->ev = (default_loop ? ev_default_loop : ev_loop_new)(flags); ev_set_userdata(loop->ev, loop); uv_signal_init(loop, &loop->child_watcher); uv__handle_unref(&loop->child_watcher); loop->child_watcher.flags |= UV__HANDLE_INTERNAL; for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) ngx_queue_init(loop->process_handles + i); if (uv_mutex_init(&loop->wq_mutex)) abort(); if (uv_async_init(loop, &loop->wq_async, uv__work_done)) abort(); uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV__HANDLE_INTERNAL; if (uv__platform_loop_init(loop, default_loop)) return -1; return 0; }
int uv_fs_poll_start(uv_fs_poll_t* handle, uv_fs_poll_cb cb, const char* path, unsigned int interval) { struct poll_ctx* ctx; uv_loop_t* loop; size_t len; if (uv__is_active(handle)) return 0; loop = handle->loop; len = strlen(path); ctx = calloc(1, sizeof(*ctx) + len); if (ctx == NULL) return uv__set_artificial_error(loop, UV_ENOMEM); ctx->loop = loop; ctx->poll_cb = cb; ctx->interval = interval ? interval : 1; ctx->start_time = uv_now(loop); ctx->parent_handle = handle; memcpy(ctx->path, path, len + 1); if (uv_timer_init(loop, &ctx->timer_handle)) abort(); ctx->timer_handle.flags |= UV__HANDLE_INTERNAL; uv__handle_unref(&ctx->timer_handle); if (uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb)) abort(); handle->poll_ctx = ctx; uv__handle_start(handle); return 0; }
int uv_loop_init(uv_loop_t* loop) { /* Initialize libuv itself first */ uv__once_init(); /* Create an I/O completion port */ loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); if (loop->iocp == NULL) return uv_translate_sys_error(GetLastError()); /* To prevent uninitialized memory access, loop->time must be initialized * to zero before calling uv_update_time for the first time. */ loop->time = 0; uv_update_time(loop); QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->handle_queue); QUEUE_INIT(&loop->active_reqs); loop->active_handles = 0; loop->pending_reqs_tail = NULL; loop->endgame_handles = NULL; RB_INIT(&loop->timers); loop->check_handles = NULL; loop->prepare_handles = NULL; loop->idle_handles = NULL; loop->next_prepare_handle = NULL; loop->next_check_handle = NULL; loop->next_idle_handle = NULL; memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets); loop->active_tcp_streams = 0; loop->active_udp_streams = 0; loop->timer_counter = 0; loop->stop_flag = 0; if (uv_mutex_init(&loop->wq_mutex)) abort(); if (uv_async_init(loop, &loop->wq_async, uv__work_done)) abort(); uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV__HANDLE_INTERNAL; return 0; }
int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) { /* TODO(bnoordhuis) Mark fs_req internal. */ uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_POLL); loop->counters.fs_poll_init++; if (uv_timer_init(loop, &handle->timer_handle)) return -1; handle->timer_handle.flags |= UV__HANDLE_INTERNAL; uv__handle_unref(&handle->timer_handle); return 0; }
int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) { uv__handle_init(loop, (uv_handle_t*)async, UV_ASYNC); loop->counters.async_init++; ev_async_init(&async->async_watcher, uv__async); async->async_cb = async_cb; /* Note: This does not have symmetry with the other libev wrappers. */ ev_async_start(loop->ev, &async->async_watcher); uv__handle_unref(async); uv__handle_start(async); return 0; }
void uv_eio_init(uv_loop_t* loop) { if (loop->flags & UV_LOOP_EIO_INITIALIZED) return; loop->flags |= UV_LOOP_EIO_INITIALIZED; uv_idle_init(loop, &loop->uv_eio_poller); uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll); loop->uv_eio_poller.flags |= UV__HANDLE_INTERNAL; loop->uv_eio_want_poll_notifier.data = loop; uv_async_init(loop, &loop->uv_eio_want_poll_notifier, uv_eio_want_poll_notifier_cb); loop->uv_eio_want_poll_notifier.flags |= UV__HANDLE_INTERNAL; uv__handle_unref(&loop->uv_eio_want_poll_notifier); uv_async_init(loop, &loop->uv_eio_done_poll_notifier, uv_eio_done_poll_notifier_cb); loop->uv_eio_done_poll_notifier.flags |= UV__HANDLE_INTERNAL; uv__handle_unref(&loop->uv_eio_done_poll_notifier); uv_once(&uv__eio_init_once_guard, uv__eio_init); }
static void uv__finish_close(uv_handle_t* handle) { /* Note: while the handle is in the UV_HANDLE_CLOSING state now, it's still * possible for it to be active in the sense that uv__is_active() returns * true. * * A good example is when the user calls uv_shutdown(), immediately followed * by uv_close(). The handle is considered active at this point because the * completion of the shutdown req is still pending. */ assert(handle->flags & UV_HANDLE_CLOSING); assert(!(handle->flags & UV_HANDLE_CLOSED)); handle->flags |= UV_HANDLE_CLOSED; switch (handle->type) { case UV_PREPARE: case UV_CHECK: case UV_IDLE: case UV_ASYNC: case UV_TIMER: case UV_PROCESS: case UV_FS_EVENT: case UV_FS_POLL: case UV_POLL: case UV_SIGNAL: break; case UV_NAMED_PIPE: case UV_TCP: case UV_TTY: uv__stream_destroy((uv_stream_t*)handle); break; case UV_UDP: uv__udp_finish_close((uv_udp_t*)handle); break; default: assert(0); break; } uv__handle_unref(handle); QUEUE_REMOVE(&handle->handle_queue); if (handle->close_cb) { handle->close_cb(handle); } }
void uv__finish_close(uv_handle_t* handle) { assert(!uv__is_active(handle)); assert(handle->flags & UV_CLOSING); assert(!(handle->flags & UV_CLOSED)); handle->flags |= UV_CLOSED; switch (handle->type) { case UV_PREPARE: case UV_CHECK: case UV_IDLE: case UV_ASYNC: case UV_TIMER: case UV_PROCESS: break; case UV_NAMED_PIPE: case UV_TCP: case UV_TTY: assert(!ev_is_active(&((uv_stream_t*)handle)->read_watcher)); assert(!ev_is_active(&((uv_stream_t*)handle)->write_watcher)); assert(((uv_stream_t*)handle)->fd == -1); uv__stream_destroy((uv_stream_t*)handle); break; case UV_UDP: uv__udp_finish_close((uv_udp_t*)handle); break; case UV_FS_EVENT: break; case UV_POLL: break; default: assert(0); break; } if (handle->close_cb) { handle->close_cb(handle); } uv__handle_unref(handle); }
static void uv__finish_close(uv_handle_t* handle) { assert(!uv__is_active(handle)); assert(handle->flags & UV_CLOSING); assert(!(handle->flags & UV_CLOSED)); handle->flags |= UV_CLOSED; switch (handle->type) { case UV_PREPARE: case UV_CHECK: case UV_IDLE: case UV_ASYNC: case UV_TIMER: case UV_PROCESS: case UV_FS_EVENT: case UV_FS_POLL: case UV_POLL: case UV_SIGNAL: break; case UV_NAMED_PIPE: case UV_TCP: case UV_TTY: uv__stream_destroy((uv_stream_t*)handle); break; case UV_UDP: uv__udp_finish_close((uv_udp_t*)handle); break; default: assert(0); break; } uv__handle_unref(handle); ngx_queue_remove(&handle->handle_queue); if (handle->close_cb) { handle->close_cb(handle); } }
int uv_loop_init(uv_loop_t* loop) { void* saved_data; int err; saved_data = loop->data; memset(loop, 0, sizeof(*loop)); loop->data = saved_data; heap_init((struct heap*) &loop->timer_heap); QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->idle_handles); QUEUE_INIT(&loop->async_handles); QUEUE_INIT(&loop->check_handles); QUEUE_INIT(&loop->prepare_handles); QUEUE_INIT(&loop->handle_queue); loop->active_handles = 0; loop->active_reqs.count = 0; loop->nfds = 0; loop->watchers = NULL; loop->nwatchers = 0; QUEUE_INIT(&loop->pending_queue); QUEUE_INIT(&loop->watcher_queue); loop->closing_handles = NULL; uv__update_time(loop); loop->async_io_watcher.fd = -1; loop->async_wfd = -1; loop->signal_pipefd[0] = -1; loop->signal_pipefd[1] = -1; loop->backend_fd = -1; loop->emfile_fd = -1; loop->timer_counter = 0; loop->stop_flag = 0; err = uv__platform_loop_init(loop); if (err) return err; uv__signal_global_once_init(); err = uv_signal_init(loop, &loop->child_watcher); if (err) goto fail_signal_init; uv__handle_unref(&loop->child_watcher); loop->child_watcher.flags |= UV__HANDLE_INTERNAL; QUEUE_INIT(&loop->process_handles); err = uv_rwlock_init(&loop->cloexec_lock); if (err) goto fail_rwlock_init; err = uv_mutex_init(&loop->wq_mutex); if (err) goto fail_mutex_init; err = uv_async_init(loop, &loop->wq_async, uv__work_done); if (err) goto fail_async_init; uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV__HANDLE_INTERNAL; return 0; fail_async_init: uv_mutex_destroy(&loop->wq_mutex); fail_mutex_init: uv_rwlock_destroy(&loop->cloexec_lock); fail_rwlock_init: uv__signal_loop_cleanup(loop); fail_signal_init: uv__platform_loop_delete(loop); return err; }
int uv__stream_try_select(uv_stream_t* stream, int fd) { /* * kqueue doesn't work with some files from /dev mount on osx. * select(2) in separate thread for those fds */ struct kevent filter[1]; struct kevent events[1]; struct timespec timeout; uv__stream_select_t* s; int fds[2]; int ret; int kq; kq = kqueue(); if (kq == -1) { fprintf(stderr, "(libuv) Failed to create kqueue (%d)\n", errno); return uv__set_sys_error(stream->loop, errno); } EV_SET(&filter[0], fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0); /* Use small timeout, because we only want to capture EINVALs */ timeout.tv_sec = 0; timeout.tv_nsec = 1; ret = kevent(kq, filter, 1, events, 1, &timeout); SAVE_ERRNO(close(kq)); if (ret == -1) return uv__set_sys_error(stream->loop, errno); if ((events[0].flags & EV_ERROR) == 0 || events[0].data != EINVAL) return 0; /* At this point we definitely know that this fd won't work with kqueue */ s = malloc(sizeof(*s)); if (s == NULL) return uv__set_artificial_error(stream->loop, UV_ENOMEM); s->fd = fd; if (uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb)) { SAVE_ERRNO(free(s)); return uv__set_sys_error(stream->loop, errno); } s->async.flags |= UV__HANDLE_INTERNAL; uv__handle_unref(&s->async); if (uv_sem_init(&s->sem, 0)) goto fatal1; if (uv_mutex_init(&s->mutex)) goto fatal2; /* Create fds for io watcher and to interrupt the select() loop. */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) goto fatal3; s->fake_fd = fds[0]; s->int_fd = fds[1]; if (uv_thread_create(&s->thread, uv__stream_osx_select, stream)) goto fatal4; s->stream = stream; stream->select = s; return 0; fatal4: close(s->fake_fd); close(s->int_fd); s->fake_fd = -1; s->int_fd = -1; fatal3: uv_mutex_destroy(&s->mutex); fatal2: uv_sem_destroy(&s->sem); fatal1: uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); return uv__set_sys_error(stream->loop, errno); }
int uv_loop_init(uv_loop_t* loop) { struct heap* timer_heap; int err; /* Initialize libuv itself first */ uv__once_init(); /* Create an I/O completion port */ loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); if (loop->iocp == NULL) return uv_translate_sys_error(GetLastError()); /* To prevent uninitialized memory access, loop->time must be initialized * to zero before calling uv_update_time for the first time. */ loop->time = 0; uv_update_time(loop); QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->handle_queue); loop->active_reqs.count = 0; loop->active_handles = 0; loop->pending_reqs_tail = NULL; loop->endgame_handles = NULL; loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap)); if (timer_heap == NULL) { err = UV_ENOMEM; goto fail_timers_alloc; } heap_init(timer_heap); loop->check_handles = NULL; loop->prepare_handles = NULL; loop->idle_handles = NULL; loop->next_prepare_handle = NULL; loop->next_check_handle = NULL; loop->next_idle_handle = NULL; memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets); loop->active_tcp_streams = 0; loop->active_udp_streams = 0; loop->timer_counter = 0; loop->stop_flag = 0; err = uv_mutex_init(&loop->wq_mutex); if (err) goto fail_mutex_init; err = uv_async_init(loop, &loop->wq_async, uv__work_done); if (err) goto fail_async_init; uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV_HANDLE_INTERNAL; err = uv__loops_add(loop); if (err) goto fail_async_init; return 0; fail_async_init: uv_mutex_destroy(&loop->wq_mutex); fail_mutex_init: uv__free(timer_heap); loop->timer_heap = NULL; fail_timers_alloc: CloseHandle(loop->iocp); loop->iocp = INVALID_HANDLE_VALUE; return err; }