Alien-uv

 view release on metacpan or  search on metacpan

libuv/test/test-callback-stack.c  view on Meta::CPAN

  ASSERT(buf->base != NULL);
}


static void close_cb(uv_handle_t* handle) {
  ASSERT(nested == 0 && "close_cb must be called from a fresh stack");

  close_cb_called++;
}


static void shutdown_cb(uv_shutdown_t* req, int status) {
  ASSERT(status == 0);
  ASSERT(nested == 0 && "shutdown_cb must be called from a fresh stack");

  shutdown_cb_called++;
}


static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
  ASSERT(nested == 0 && "read_cb must be called from a fresh stack");

  printf("Read. nread == %d\n", (int)nread);
  free(buf->base);

  if (nread == 0) {
    return;

  } else if (nread < 0) {
    ASSERT(nread == UV_EOF);

    nested++;
    uv_close((uv_handle_t*)tcp, close_cb);
    nested--;

    return;
  }

  bytes_received += nread;

  /* We call shutdown here because when bytes_received == sizeof MESSAGE there
   * will be no more data sent nor received, so here it would be possible for a
   * backend to call shutdown_cb immediately and *not* from a fresh stack. */
  if (bytes_received == sizeof MESSAGE) {
    nested++;

    puts("Shutdown");

    if (uv_shutdown(&shutdown_req, (uv_stream_t*)tcp, shutdown_cb)) {
      FATAL("uv_shutdown failed");
    }
    nested--;
  }
}


static void timer_cb(uv_timer_t* handle) {
  ASSERT(handle == &timer);
  ASSERT(nested == 0 && "timer_cb must be called from a fresh stack");

  puts("Timeout complete. Now read data...");

  nested++;
  if (uv_read_start((uv_stream_t*)&client, alloc_cb, read_cb)) {
    FATAL("uv_read_start failed");
  }
  nested--;

  timer_cb_called++;

  uv_close((uv_handle_t*)handle, close_cb);
}


static void write_cb(uv_write_t* req, int status) {
  int r;

  ASSERT(status == 0);
  ASSERT(nested == 0 && "write_cb must be called from a fresh stack");

  puts("Data written. 500ms timeout...");

  /* After the data has been sent, we're going to wait for a while, then start
   * reading. This makes us certain that the message has been echoed back to
   * our receive buffer when we start reading. This maximizes the temptation
   * for the backend to use dirty stack for calling read_cb. */
  nested++;
  r = uv_timer_init(uv_default_loop(), &timer);
  ASSERT(r == 0);
  r = uv_timer_start(&timer, timer_cb, 500, 0);
  ASSERT(r == 0);
  nested--;

  write_cb_called++;
}


static void connect_cb(uv_connect_t* req, int status) {
  uv_buf_t buf;

  puts("Connected. Write some data to echo server...");

  ASSERT(status == 0);
  ASSERT(nested == 0 && "connect_cb must be called from a fresh stack");

  nested++;

  buf.base = (char*) &MESSAGE;
  buf.len = sizeof MESSAGE;

  if (uv_write(&write_req, (uv_stream_t*)req->handle, &buf, 1, write_cb)) {
    FATAL("uv_write failed");
  }

  nested--;

  connect_cb_called++;
}


TEST_IMPL(callback_stack) {

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.580 second using v1.00-cache-2.02-grep-82fe00e-cpan-2c419f77a38b )