void uv__stream_close(uv_stream_t* handle) { #if defined(__APPLE__) /* Terminate select loop first */ if (handle->select != NULL) { uv__stream_select_t* s; s = handle->select; uv_sem_post(&s->sem); uv__stream_osx_interrupt_select(handle); uv_thread_join(&s->thread); uv_sem_destroy(&s->sem); uv_mutex_destroy(&s->mutex); close(s->fake_fd); close(s->int_fd); uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); handle->select = NULL; } #endif /* defined(__APPLE__) */ uv_read_stop(handle); uv__io_close(handle->loop, &handle->io_watcher); close(handle->io_watcher.fd); handle->io_watcher.fd = -1; if (handle->accepted_fd >= 0) { close(handle->accepted_fd); handle->accepted_fd = -1; } assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT)); }
int uv_read_stop(uv_stream_t* stream) { uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN); uv__handle_stop(stream); stream->flags &= ~UV_STREAM_READING; #if defined(__APPLE__) /* Notify select() thread about state change */ if (stream->select != NULL) uv__stream_osx_interrupt_select(stream); #endif /* defined(__APPLE__) */ stream->read_cb = NULL; stream->read2_cb = NULL; stream->alloc_cb = NULL; return 0; }
static int uv__read_start_common(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb, uv_read2_cb read2_cb) { assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE || stream->type == UV_TTY); if (stream->flags & UV_CLOSING) { uv__set_sys_error(stream->loop, EINVAL); return -1; } /* 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; #if defined(__APPLE__) /* Notify select() thread about state change */ if (stream->select != NULL) uv__stream_osx_interrupt_select(stream); #endif /* defined(__APPLE__) */ /* 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->read2_cb = read2_cb; stream->alloc_cb = alloc_cb; uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN); uv__handle_start(stream); return 0; }