int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb poll_cb) { int ev_events; assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0); assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); if (events == 0) { uv__poll_stop(handle); return 0; } ev_events = 0; if (events & UV_READABLE) ev_events |= EV_READ; if (events & UV_WRITABLE) ev_events |= EV_WRITE; ev_io_set(&handle->io_watcher, handle->fd, ev_events); ev_io_start(handle->loop->ev, &handle->io_watcher); handle->poll_cb = poll_cb; uv__handle_start(handle); return 0; }
int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb) { assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE || stream->type == UV_TTY); if (stream->flags & UV_CLOSING) return -EINVAL; /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just * expresses the desired state of the user. */ stream->flags |= UV_STREAM_READING; /* TODO: try to do the read inline? */ /* TODO: keep track of tcp state. If we've gotten a EOF then we should * not start the IO watcher. */ assert(uv__stream_fd(stream) >= 0); assert(alloc_cb); stream->read_cb = read_cb; stream->alloc_cb = alloc_cb; uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN); uv__handle_start(stream); 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_timer_start(uv_timer_t* handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat) { uint64_t clamped_timeout; if (cb == NULL) return UV_EINVAL; if (uv__is_active(handle)) uv_timer_stop(handle); clamped_timeout = handle->loop->time + timeout; if (clamped_timeout < timeout) clamped_timeout = (uint64_t) -1; handle->timer_cb = cb; handle->timeout = clamped_timeout; handle->repeat = repeat; /* start_id is the second index to be compared in uv__timer_cmp() */ handle->start_id = handle->loop->timer_counter++; heap_insert(timer_heap(handle->loop), (struct heap_node*) &handle->heap_node, timer_less_than); uv__handle_start(handle); return 0; }
static void uv_fs_event_init_handle(uv_loop_t* loop, uv_fs_event_t* handle, const char* filename, uv_fs_event_cb cb) { uv_handle_init(loop, (uv_handle_t*) handle); handle->type = UV_FS_EVENT; handle->cb = cb; handle->dir_handle = INVALID_HANDLE_VALUE; handle->buffer = NULL; handle->req_pending = 0; handle->filew = NULL; handle->short_filew = NULL; handle->dirw = NULL; uv_req_init(loop, (uv_req_t*)&handle->req); handle->req.type = UV_FS_EVENT_REQ; handle->req.data = (void*)handle; handle->filename = strdup(filename); if (!handle->filename) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } uv__handle_start(handle); loop->counters.fs_event_init++; }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* filename, unsigned int flags) { int portfd; int first_run; if (uv__is_active(handle)) return -EINVAL; first_run = 0; if (handle->loop->fs_fd == -1) { portfd = port_create(); if (portfd == -1) return -errno; handle->loop->fs_fd = portfd; first_run = 1; } uv__handle_start(handle); handle->filename = strdup(filename); handle->fd = PORT_UNUSED; handle->cb = cb; memset(&handle->fo, 0, sizeof handle->fo); handle->fo.fo_name = handle->filename; uv__fs_event_rearm(handle); /* FIXME(bnoordhuis) Check return code. */ if (first_run) { uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd); uv__io_start(handle->loop, &handle->loop->fs_event_watcher, UV__POLLIN); } return 0; }
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle, const char* filename, uv_fs_event_cb cb, int flags) { int portfd; int first_run = 0; if (loop->fs_fd == -1) { if ((portfd = port_create()) == -1) { uv__set_sys_error(loop, errno); return -1; } loop->fs_fd = portfd; first_run = 1; } uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); uv__handle_start(handle); /* FIXME shouldn't start automatically */ handle->filename = strdup(filename); handle->fd = PORT_UNUSED; handle->cb = cb; memset(&handle->fo, 0, sizeof handle->fo); handle->fo.fo_name = handle->filename; uv__fs_event_rearm(handle); if (first_run) { uv__io_init(&loop->fs_event_watcher, uv__fs_event_read, portfd); uv__io_start(loop, &loop->fs_event_watcher, UV__POLLIN); } return 0; }
static int uv__send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[], int bufcnt, struct sockaddr* addr, socklen_t addrlen, uv_udp_send_cb send_cb) { assert(bufcnt > 0); if (uv__udp_maybe_deferred_bind(handle, addr->sa_family)) return -1; uv__req_init(handle->loop, req, UV_UDP_SEND); assert(addrlen <= sizeof(req->addr)); memcpy(&req->addr, addr, addrlen); req->send_cb = send_cb; req->handle = handle; req->bufcnt = bufcnt; if (bufcnt <= (int) ARRAY_SIZE(req->bufsml)) { req->bufs = req->bufsml; } else if ((req->bufs = malloc(bufcnt * sizeof(bufs[0]))) == NULL) { uv__set_sys_error(handle->loop, ENOMEM); return -1; } memcpy(req->bufs, bufs, bufcnt * sizeof(bufs[0])); ngx_queue_insert_tail(&handle->write_queue, &req->queue); uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT); uv__handle_start(handle); return 0; }
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle, const char* filename, uv_fs_event_cb cb, int flags) { int fd; loop->counters.fs_event_init++; /* We don't support any flags yet. */ assert(!flags); /* TODO open asynchronously - but how do we report back errors? */ if ((fd = open(filename, O_RDONLY)) == -1) { uv__set_sys_error(loop, errno); return -1; } uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); uv__handle_start(handle); /* FIXME shouldn't start automatically */ handle->filename = strdup(filename); handle->fflags = 0; handle->cb = cb; handle->fd = fd; uv__fs_event_start(handle); return 0; }
int uv_fs_poll_start(uv_fs_poll_t* handle, uv_fs_poll_cb cb, const char* path, unsigned int interval) { uv_fs_t* req; size_t len; if (uv__is_active(handle)) return 0; len = strlen(path) + 1; req = malloc(sizeof(*req) + len); if (req == NULL) return uv__set_artificial_error(handle->loop, UV_ENOMEM); req->data = handle; handle->path = memcpy(req + 1, path, len); handle->fs_req = req; handle->poll_cb = cb; handle->interval = interval ? interval : 1; handle->start_time = uv_now(handle->loop); handle->busy_polling = 0; memset(&handle->statbuf, 0, sizeof(handle->statbuf)); if (uv_fs_stat(handle->loop, handle->fs_req, handle->path, poll_cb)) abort(); uv__handle_start(handle); return 0; }
int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) { int events; assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0); assert(!uv__is_closing(handle)); uv__poll_stop(handle); if (pevents == 0) return 0; events = 0; if (pevents & UV_READABLE) events |= POLLIN; if (pevents & UV_WRITABLE) events |= POLLOUT; if (pevents & UV_DISCONNECT) events |= UV__POLLRDHUP; uv__io_start(handle->loop, &handle->io_watcher, events); uv__handle_start(handle); handle->poll_cb = poll_cb; return 0; }
void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) { uv_signal_stop(handle); if (handle->pending_signum == 0) { uv__handle_start(handle); uv_want_endgame(loop, (uv_handle_t*) handle); } }
static void uv__udp_start_watcher(uv_udp_t* handle, uv__io_t* w, uv__io_cb cb, int events) { if (uv__io_active(w)) return; uv__io_init(w, cb, handle->fd, events); uv__io_start(handle->loop, w); uv__handle_start(handle); }
static void uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) { handle->events = 0; uv__handle_start(handle); if (handle->submitted_events_1 == 0 && handle->submitted_events_2 == 0) { uv_want_endgame(loop, (uv_handle_t*) handle); } }
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC); handle->async_sent = 0; handle->async_cb = async_cb; QUEUE_INSERT_TAIL(&loop->async_handles, &handle->queue); uv__handle_start(handle); return 0; }
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) { uv_udp_recv_stop(handle); closesocket(handle->socket); uv__handle_start(handle); if (handle->reqs_pending == 0) { uv_want_endgame(loop, (uv_handle_t*) handle); } }
void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) { if (handle->dir_handle != INVALID_HANDLE_VALUE) { CloseHandle(handle->dir_handle); handle->dir_handle = INVALID_HANDLE_VALUE; } if (!handle->req_pending) { uv_want_endgame(loop, (uv_handle_t*)handle); } uv__handle_start(handle); }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* filename, unsigned int flags) { #ifdef HAVE_SYS_AHAFS_EVPRODS_H int fd, rc, str_offset = 0; char cwd[PATH_MAX]; char absolute_path[PATH_MAX]; char readlink_cwd[PATH_MAX]; /* Figure out whether filename is absolute or not */ if (filename[0] == '/') { /* We have absolute pathname */ snprintf(absolute_path, sizeof(absolute_path), "%s", filename); } else { /* We have a relative pathname, compose the absolute pathname */ snprintf(cwd, sizeof(cwd), "/proc/%lu/cwd", (unsigned long) getpid()); rc = readlink(cwd, readlink_cwd, sizeof(readlink_cwd) - 1); if (rc < 0) return rc; /* readlink does not null terminate our string */ readlink_cwd[rc] = '\0'; if (filename[0] == '.' && filename[1] == '/') str_offset = 2; snprintf(absolute_path, sizeof(absolute_path), "%s%s", readlink_cwd, filename + str_offset); } if (uv__is_ahafs_mounted() < 0) /* /aha checks failed */ return UV_ENOSYS; /* Setup ahafs */ rc = uv__setup_ahafs((const char *)absolute_path, &fd); if (rc != 0) return rc; /* Setup/Initialize all the libuv routines */ uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__ahafs_event, fd); handle->path = uv__strdup(filename); handle->cb = cb; handle->dir_filename = NULL; uv__io_start(handle->loop, &handle->event_watcher, POLLIN); return 0; #else return -ENOSYS; #endif }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) { struct watcher_list* w; int events; int err; int wd; if (uv__is_active(handle)) return -EINVAL; err = init_inotify(handle->loop); if (err) return err; events = UV__IN_ATTRIB | UV__IN_CREATE | UV__IN_MODIFY | UV__IN_DELETE | UV__IN_DELETE_SELF | UV__IN_MOVE_SELF | UV__IN_MOVED_FROM | UV__IN_MOVED_TO; wd = uv__inotify_add_watch(handle->loop->inotify_fd, path, events); if (wd == -1) return -errno; w = find_watcher(handle->loop, wd); if (w) goto no_insert; w = uv__malloc(sizeof(*w) + strlen(path) + 1); if (w == NULL) return -ENOMEM; w->wd = wd; w->path = strcpy((char*)(w + 1), path); QUEUE_INIT(&w->watchers); w->iterating = 0; RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w); no_insert: uv__handle_start(handle); QUEUE_INSERT_TAIL(&w->watchers, &handle->watchers); handle->path = w->path; handle->cb = cb; handle->wd = wd; return 0; }
static void uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) { handle->events = 0; uv__handle_start(handle); if (handle->submitted_events_1 == 0 && handle->submitted_events_2 == 0) { uv_want_endgame(loop, (uv_handle_t*) handle); } else { /* Cancel outstanding poll requests by executing another, unique poll */ /* request that forces the outstanding ones to return. */ uv__fast_poll_cancel_poll_req(loop, handle); } }
int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr, unsigned int addrlen, uv_udp_send_cb send_cb) { int err; int empty_queue; assert(nbufs > 0); err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0); if (err) return err; /* It's legal for send_queue_count > 0 even when the write_queue is empty; * it means there are error-state requests in the write_completed_queue that * will touch up send_queue_size/count later. */ empty_queue = (handle->send_queue_count == 0); uv__req_init(handle->loop, req, UV_UDP_SEND); assert(addrlen <= sizeof(req->addr)); memcpy(&req->addr, addr, addrlen); req->send_cb = send_cb; req->handle = handle; req->nbufs = nbufs; req->bufs = req->bufsml; if (nbufs > ARRAY_SIZE(req->bufsml)) req->bufs = uv__malloc(nbufs * sizeof(bufs[0])); if (req->bufs == NULL) return -ENOMEM; memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0])); handle->send_queue_size += uv__count_bufs(req->bufs, req->nbufs); handle->send_queue_count++; QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue); uv__handle_start(handle); if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) { uv__udp_sendmsg(handle); } else { uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT); } 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; }
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) { #if defined(__APPLE__) struct stat statbuf; #endif /* defined(__APPLE__) */ int fd; if (uv__is_active(handle)) return -EINVAL; /* TODO open asynchronously - but how do we report back errors? */ fd = open(path, O_RDONLY); if (fd == -1) return -errno; uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__fs_event, fd); handle->path = uv__strdup(path); handle->cb = cb; #if defined(__APPLE__) /* Nullify field to perform checks later */ handle->cf_cb = NULL; handle->realpath = NULL; handle->realpath_len = 0; handle->cf_flags = flags; if (fstat(fd, &statbuf)) goto fallback; /* FSEvents works only with directories */ if (!(statbuf.st_mode & S_IFDIR)) goto fallback; /* The fallback fd is no longer needed */ uv__close(fd); handle->event_watcher.fd = -1; return uv__fsevents_init(handle); fallback: #endif /* defined(__APPLE__) */ uv__io_start(handle->loop, &handle->event_watcher, POLLIN); return 0; }
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { int err; err = uv__async_start(loop); if (err) return err; uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC); handle->async_cb = async_cb; handle->pending = 0; QUEUE_INSERT_TAIL(&loop->async_handles, &handle->queue); uv__handle_start(handle); return 0; }
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { uv_req_t* req; uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC); handle->async_sent = 0; handle->async_cb = async_cb; req = &handle->async_req; uv_req_init(loop, req); req->type = UV_WAKEUP; req->data = handle; uv__handle_start(handle); return 0; }
int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { uv_err_t err; /* If the user supplies signum == 0, then return an error already. If the */ /* signum is otherwise invalid then uv__signal_register will find out */ /* eventually. */ if (signum == 0) { uv__set_artificial_error(handle->loop, UV_EINVAL); return -1; } /* Short circuit: if the signal watcher is already watching {signum} don't */ /* go through the process of deregistering and registering the handler. */ /* Additionally, this avoids pending signals getting lost in the (small) */ /* time frame that handle->signum == 0. */ if (signum == handle->signum) { handle->signal_cb = signal_cb; return 0; } /* If the signal handler was already active, stop it first. */ if (handle->signum != 0) { int r = uv_signal_stop(handle); /* uv_signal_stop is infallible. */ assert(r == 0); } EnterCriticalSection(&uv__signal_lock); err = uv__signal_register(signum); if (err.code != UV_OK) { /* Uh-oh, didn't work. */ handle->loop->last_err = err; LeaveCriticalSection(&uv__signal_lock); return -1; } handle->signum = signum; RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle); LeaveCriticalSection(&uv__signal_lock); handle->signal_cb = signal_cb; uv__handle_start(handle); return 0; }
int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { uv_req_t* req; uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); handle->pending_signum = 0; handle->signum = 0; handle->signal_cb = NULL; req = &handle->signal_req; uv_req_init(loop, req); req->type = UV_SIGNAL_REQ; req->data = handle; uv__handle_start(handle); return 0; }
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle, const char* filename, uv_fs_event_cb cb, int flags) { int fd; #if defined(__APPLE__) struct stat statbuf; #endif /* defined(__APPLE__) */ /* We don't support any flags yet. */ assert(!flags); /* TODO open asynchronously - but how do we report back errors? */ if ((fd = open(filename, O_RDONLY)) == -1) { uv__set_sys_error(loop, errno); return -1; } uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); uv__handle_start(handle); /* FIXME shouldn't start automatically */ handle->filename = strdup(filename); handle->fflags = 0; handle->cb = cb; handle->fd = fd; #if defined(__APPLE__) /* Nullify field to perform checks later */ handle->cf_eventstream = NULL; if (fstat(fd, &statbuf)) goto fallback; /* FSEvents works only with directories */ if (!(statbuf.st_mode & S_IFDIR)) goto fallback; return uv__fsevents_init(handle); fallback: #endif /* defined(__APPLE__) */ uv__fs_event_start(handle); return 0; }
int uv_timer_start(uv_timer_t* handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat) { if (uv__is_active(handle)) uv_timer_stop(handle); handle->timer_cb = cb; handle->timeout = handle->loop->time + timeout; handle->repeat = repeat; /* start_id is the second index to be compared in uv__timer_cmp() */ handle->start_id = handle->loop->timer_counter++; RB_INSERT(uv__timers, &handle->loop->timer_handles, handle); uv__handle_start(handle); return 0; }
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) { uv__handle_start(handle); if (handle->wait_handle != INVALID_HANDLE_VALUE) { /* This blocks until either the wait was cancelled, or the callback has */ /* completed. */ BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE); if (!r) { /* This should never happen, and if it happens, we can't recover... */ uv_fatal_error(GetLastError(), "UnregisterWaitEx"); } handle->wait_handle = INVALID_HANDLE_VALUE; } if (!handle->exit_cb_pending) { uv_want_endgame(loop, (uv_handle_t*)handle); } }