示例#1
0
文件: evcom.c 项目: bernd/node
/* Internal callback. called by stream->timeout_watcher */
static void
on_timeout (EV_P_ ev_timer *watcher, int revents)
{
  evcom_stream *stream = watcher->data;

#if EV_MULTIPLICITY
  assert(stream->loop == loop);
#endif
  assert(revents == EV_TIMEOUT);
  assert(watcher == &stream->timeout_watcher);

  if (PAUSED(stream)) {
    ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
    return;
  }

  if (stream->on_timeout) stream->on_timeout(stream);

  // Hack to get error in Node on 'close' event.
  // should probably be made into a proper error code.
  stream->errorno = 1;

  ev_timer_stop(EV_A_ watcher);
  evcom_stream_force_close(stream);

  if (stream->on_close) stream->on_close(stream);
}
示例#2
0
文件: evcom.c 项目: blaine/node
/* Internal callback. called by stream->timeout_watcher */
static void
on_timeout (EV_P_ ev_timer *watcher, int revents)
{
  evcom_stream *stream = watcher->data;

#if EV_MULTIPLICITY
  assert(stream->loop == loop);
#endif
  assert(revents == EV_TIMEOUT);
  assert(watcher == &stream->timeout_watcher);

  if (PAUSED(stream)) {
    ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
    return;
  }

  if (stream->on_timeout) stream->on_timeout(stream);

  evcom_stream_force_close(stream);

  if (stream->on_close) stream->on_close(stream);
}
示例#3
0
文件: evcom.c 项目: bernd/node
static int
stream_recv__data (evcom_stream *stream)
{
  char buf[EVCOM_CHUNKSIZE];
  size_t buf_size = EVCOM_CHUNKSIZE;
  ssize_t recved;

  while (READABLE(stream)) {
    assert(CONNECTED(stream));

    if (PAUSED(stream)) {
      stream->recv_action = stream_recv__wait_for_resume;
      return OKAY;
    }


#if EVCOM_HAVE_GNUTLS
    if (SECURE(stream)) {
      recved = gnutls_record_recv(stream->session, buf, buf_size);

      if (gnutls_error_is_fatal(recved)) {
        stream->gnutls_errorno = recved;
        stream->recv_action = stream_recv__close;
        return OKAY;
      }

      if (recved == GNUTLS_E_INTERRUPTED || recved == GNUTLS_E_AGAIN) {
        if (1 == gnutls_record_get_direction((stream)->session)) {
          fprintf(stderr, "(evcom) gnutls recv: unexpected switch direction!\n");
          ev_io_stop(D_LOOP_(stream) &(stream)->read_watcher); 
          ev_io_start(D_LOOP_(stream) &(stream)->write_watcher);
        }
        return AGAIN;
      }

      /* A server may also receive GNUTLS_E_REHANDSHAKE when a client has
       * initiated a andshake. In that case the server can only initiate a
       * handshake or terminate the connection. */
      if (recved == GNUTLS_E_REHANDSHAKE) {
        assert(WRITABLE(stream));
        stream->recv_action = stream__handshake;
        stream->send_action = stream__handshake;
        return OKAY;
      }
    } else 
#endif /* EVCOM_HAVE_GNUTLS */
    {
      recved = read(stream->recvfd, buf, buf_size);
    }

    if (recved < 0) {
      if (errno == EAGAIN || errno == EINTR) {
        assert(stream->recv_action == stream_recv__data);
        return AGAIN;
      } 
      
      if (errno != ECONNRESET) {
        evcom_perror("recv()", stream->errorno);
      }

      stream->errorno = errno;
      stream->recv_action = stream_recv__close;
      return OKAY;
    }

    ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);

    assert(recved >= 0);

    if (recved == 0) {
      stream->flags &= ~EVCOM_READABLE;
      ev_io_stop(D_LOOP_(stream) &stream->read_watcher);
      stream->recv_action = stream_recv__wait_for_close;
    }

    /* NOTE: EOF is signaled with recved == 0 on callback */
    if (stream->on_read) stream->on_read(stream, buf, recved);

    if (recved == 0) {
      return OKAY;
    }
  }
  return AGAIN;
}