Esempio n. 1
0
static void uv__drain(uv_handle_t* handle) {
    assert(!uv_write_queue_head(handle));
    assert(handle->write_queue_size == 0);

    ev_io_stop(EV_DEFAULT_ &handle->write_watcher);

    /* Shutdown? */
    if (uv_flag_is_set(handle, UV_SHUTTING) &&
            !uv_flag_is_set(handle, UV_CLOSING) &&
            !uv_flag_is_set(handle, UV_SHUT)) {
        assert(handle->shutdown_req);

        uv_req_t* req = handle->shutdown_req;
        uv_shutdown_cb cb = req->cb;

        if (shutdown(handle->fd, SHUT_WR)) {
            /* Error. Nothing we can do, close the handle. */
            uv_err_new(handle, errno);
            uv_close(handle);
            if (cb) cb(req, -1);
        } else {
            uv_err_new(handle, 0);
            uv_flag_set(handle, UV_SHUT);
            if (cb) cb(req, 0);
        }
    }
}
Esempio n. 2
0
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
  uv_tcp_t* tcp = (uv_tcp_t*)handle;
  assert(handle->type == UV_TCP &&
      "uv_shutdown (unix) only supports uv_tcp_t right now");
  assert(tcp->fd >= 0);

  /* Initialize request */
  uv__req_init((uv_req_t*)req);
  req->handle = handle;
  req->cb = cb;

  if (uv_flag_is_set((uv_handle_t*)tcp, UV_SHUT) ||
      uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSED) ||
      uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSING)) {
    return -1;
  }

  tcp->shutdown_req = req;
  req->type = UV_SHUTDOWN;

  uv_flag_set((uv_handle_t*)tcp, UV_SHUTTING);

  ev_io_start(EV_DEFAULT_UC_ &tcp->write_watcher);

  return 0;
}
Esempio n. 3
0
static void uv__drain(uv_tcp_t* tcp) {
  uv_shutdown_t* req;

  assert(!uv_write_queue_head(tcp));
  assert(tcp->write_queue_size == 0);

  ev_io_stop(EV_DEFAULT_ &tcp->write_watcher);

  /* Shutdown? */
  if (uv_flag_is_set((uv_handle_t*)tcp, UV_SHUTTING) &&
      !uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSING) &&
      !uv_flag_is_set((uv_handle_t*)tcp, UV_SHUT)) {
    assert(tcp->shutdown_req);

    req = tcp->shutdown_req;

    if (shutdown(tcp->fd, SHUT_WR)) {
      /* Error. Report it. User should call uv_close(). */
      uv_err_new((uv_handle_t*)tcp, errno);
      if (req->cb) {
        req->cb(req, -1);
      }
    } else {
      uv_err_new((uv_handle_t*)tcp, 0);
      uv_flag_set((uv_handle_t*)tcp, UV_SHUT);
      if (req->cb) {
        req->cb(req, 0);
      }
    }
  }
}
Esempio n. 4
0
int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
  uv_tcp_t* tcp = (uv_tcp_t*)stream;

  /* The UV_READING flag is irrelevant of the state of the tcp - it just
   * expresses the desired state of the user.
   */
  uv_flag_set((uv_handle_t*)tcp, UV_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(tcp->fd >= 0);
  assert(alloc_cb);

  tcp->read_cb = read_cb;
  tcp->alloc_cb = alloc_cb;

  /* These should have been set by uv_tcp_init. */
  assert(tcp->read_watcher.data == tcp);
  assert(tcp->read_watcher.cb == uv__tcp_io);

  ev_io_start(EV_DEFAULT_UC_ &tcp->read_watcher);
  return 0;
}
Esempio n. 5
0
void uv__finish_close(uv_handle_t* handle) {
    assert(uv_flag_is_set(handle, UV_CLOSING));
    assert(!uv_flag_is_set(handle, UV_CLOSED));
    uv_flag_set(handle, UV_CLOSED);

    switch (handle->type) {
    case UV_TCP:
        /* XXX Is it necessary to stop these watchers here? weren't they
         * supposed to be stopped in uv_close()?
         */
        ev_io_stop(EV_DEFAULT_ &handle->write_watcher);
        ev_io_stop(EV_DEFAULT_ &handle->read_watcher);

        assert(!ev_is_active(&handle->read_watcher));
        assert(!ev_is_active(&handle->write_watcher));

        close(handle->fd);
        handle->fd = -1;

        if (handle->accepted_fd >= 0) {
            close(handle->accepted_fd);
            handle->accepted_fd = -1;
        }
        break;

    case UV_PREPARE:
        assert(!ev_is_active(&handle->prepare_watcher));
        break;

    case UV_CHECK:
        assert(!ev_is_active(&handle->check_watcher));
        break;

    case UV_IDLE:
        assert(!ev_is_active(&handle->idle_watcher));
        break;

    case UV_ASYNC:
        assert(!ev_is_active(&handle->async_watcher));
        break;

    case UV_TIMER:
        assert(!ev_is_active(&handle->timer_watcher));
        break;

    default:
        assert(0);
        break;
    }

    ev_idle_stop(EV_DEFAULT_ &handle->next_watcher);

    if (handle->close_cb) {
        handle->close_cb(handle, 0);
    }

    ev_unref(EV_DEFAULT_UC);
}
Esempio n. 6
0
int uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
  uv_tcp_t* tcp;
  uv_async_t* async;
  uv_timer_t* timer;

  handle->close_cb = close_cb;

  switch (handle->type) {
    case UV_TCP:
      tcp = (uv_tcp_t*) handle;
      uv_read_stop((uv_stream_t*)tcp);
      ev_io_stop(EV_DEFAULT_ &tcp->write_watcher);
      break;

    case UV_PREPARE:
      uv_prepare_stop((uv_prepare_t*) handle);
      break;

    case UV_CHECK:
      uv_check_stop((uv_check_t*) handle);
      break;

    case UV_IDLE:
      uv_idle_stop((uv_idle_t*) handle);
      break;

    case UV_ASYNC:
      async = (uv_async_t*)handle;
      ev_async_stop(EV_DEFAULT_ &async->async_watcher);
      ev_ref(EV_DEFAULT_UC);
      break;

    case UV_TIMER:
      timer = (uv_timer_t*)handle;
      if (ev_is_active(&timer->timer_watcher)) {
        ev_ref(EV_DEFAULT_UC);
      }
      ev_timer_stop(EV_DEFAULT_ &timer->timer_watcher);
      break;

    default:
      assert(0);
      return -1;
  }

  uv_flag_set(handle, UV_CLOSING);

  /* This is used to call the on_close callback in the next loop. */
  ev_idle_start(EV_DEFAULT_ &handle->next_watcher);
  ev_feed_event(EV_DEFAULT_ &handle->next_watcher, EV_IDLE);
  assert(ev_is_pending(&handle->next_watcher));

  return 0;
}
Esempio n. 7
0
int uv_close(uv_handle_t* handle) {
    switch (handle->type) {
    case UV_TCP:
        ev_io_stop(EV_DEFAULT_ &handle->write_watcher);
        ev_io_stop(EV_DEFAULT_ &handle->read_watcher);
        break;

    case UV_PREPARE:
        uv_prepare_stop(handle);
        break;

    case UV_CHECK:
        uv_check_stop(handle);
        break;

    case UV_IDLE:
        uv_idle_stop(handle);
        break;

    case UV_ASYNC:
        ev_async_stop(EV_DEFAULT_ &handle->async_watcher);
        ev_ref(EV_DEFAULT_UC);
        break;

    case UV_TIMER:
        if (ev_is_active(&handle->timer_watcher)) {
            ev_ref(EV_DEFAULT_UC);
        }
        ev_timer_stop(EV_DEFAULT_ &handle->timer_watcher);
        break;

    default:
        assert(0);
        return -1;
    }

    uv_flag_set(handle, UV_CLOSING);

    /* This is used to call the on_close callback in the next loop. */
    ev_idle_start(EV_DEFAULT_ &handle->next_watcher);
    ev_feed_event(EV_DEFAULT_ &handle->next_watcher, EV_IDLE);
    assert(ev_is_pending(&handle->next_watcher));

    return 0;
}
Esempio n. 8
0
int uv_shutdown(uv_req_t* req) {
    uv_handle_t* handle = req->handle;
    assert(handle->fd >= 0);

    if (uv_flag_is_set(handle, UV_SHUT) ||
            uv_flag_is_set(handle, UV_CLOSED) ||
            uv_flag_is_set(handle, UV_CLOSING)) {
        return -1;
    }

    handle->shutdown_req = req;
    req->type = UV_SHUTDOWN;

    uv_flag_set(handle, UV_SHUTTING);

    ev_io_start(EV_DEFAULT_UC_ &handle->write_watcher);

    return 0;
}
Esempio n. 9
0
int uv_read_start(uv_handle_t* handle, uv_read_cb cb) {
    /* The UV_READING flag is irrelevant of the state of the handle - it just
     * expresses the desired state of the user.
     */
    uv_flag_set(handle, UV_READING);

    /* TODO: try to do the read inline? */
    /* TODO: keep track of handle state. If we've gotten a EOF then we should
     * not start the IO watcher.
     */
    assert(handle->fd >= 0);
    handle->read_cb = cb;

    /* These should have been set by uv_tcp_init. */
    assert(handle->read_watcher.data == handle);
    assert(handle->read_watcher.cb == uv__tcp_io);

    ev_io_start(EV_DEFAULT_UC_ &handle->read_watcher);
    return 0;
}
Esempio n. 10
0
int uv_shutdown(uv_req_t* req) {
  uv_tcp_t* tcp = (uv_tcp_t*)req->handle;
  assert(tcp->fd >= 0);
  assert(tcp->type == UV_TCP);

  if (uv_flag_is_set((uv_handle_t*)tcp, UV_SHUT) ||
      uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSED) ||
      uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSING)) {
    return -1;
  }

  tcp->shutdown_req = req;
  req->type = UV_SHUTDOWN;

  uv_flag_set((uv_handle_t*)tcp, UV_SHUTTING);

  ev_io_start(EV_DEFAULT_UC_ &tcp->write_watcher);

  return 0;
}