예제 #1
0
static void validate_tree(nghttp2_stream *stream) {
  nghttp2_stream *si;

  if (!stream) {
    return;
  }

  for (; stream->dep_prev; stream = stream->dep_prev)
    ;

  assert(stream->stream_id == 0);
  assert(!stream->queued);

  fprintf(stderr, "checking...\n");
  if (nghttp2_pq_empty(&stream->obq)) {
    fprintf(stderr, "root obq empty\n");
    for (si = stream->dep_next; si; si = si->sib_next) {
      ensure_inactive(si);
    }
  } else {
    for (si = stream->dep_next; si; si = si->sib_next) {
      check_queued(si);
    }
  }

  check_sum_dep(stream);
  check_dep_prev(stream);
}
예제 #2
0
static void ensure_inactive(nghttp2_stream *stream) {
  nghttp2_stream *si;

  if (stream->queued) {
    fprintf(stderr, "stream(%p)=%d, stream->queued = 1; want 0\n", stream,
            stream->stream_id);
    assert(0);
  }

  if (stream_active(stream)) {
    fprintf(stderr, "stream(%p)=%d, stream_active(stream) = 1; want 0\n",
            stream, stream->stream_id);
    assert(0);
  }

  if (!nghttp2_pq_empty(&stream->obq)) {
    fprintf(stderr, "stream(%p)=%d, nghttp2_pq_size() = %zu; want 0\n", stream,
            stream->stream_id, nghttp2_pq_size(&stream->obq));
    assert(0);
  }

  for (si = stream->dep_next; si; si = si->sib_next) {
    ensure_inactive(si);
  }
}
예제 #3
0
static int stream_update_dep_on_detach_item(nghttp2_stream *stream) {
  if (nghttp2_pq_empty(&stream->obq)) {
    stream_obq_remove(stream);
  }

  validate_tree(stream);

  return 0;
}
예제 #4
0
void test_nghttp2_pq(void) {
  int i;
  nghttp2_pq pq;
  nghttp2_pq_init(&pq, pq_compar);
  CU_ASSERT(nghttp2_pq_empty(&pq));
  CU_ASSERT(0 == nghttp2_pq_size(&pq));
  CU_ASSERT(0 == nghttp2_pq_push(&pq, (void *)"foo"));
  CU_ASSERT(0 == nghttp2_pq_empty(&pq));
  CU_ASSERT(1 == nghttp2_pq_size(&pq));
  CU_ASSERT(strcmp("foo", nghttp2_pq_top(&pq)) == 0);
  CU_ASSERT(0 == nghttp2_pq_push(&pq, (void *)"bar"));
  CU_ASSERT(strcmp("bar", nghttp2_pq_top(&pq)) == 0);
  CU_ASSERT(0 == nghttp2_pq_push(&pq, (void *)"baz"));
  CU_ASSERT(strcmp("bar", nghttp2_pq_top(&pq)) == 0);
  CU_ASSERT(0 == nghttp2_pq_push(&pq, (void *)"C"));
  CU_ASSERT(4 == nghttp2_pq_size(&pq));
  CU_ASSERT(strcmp("C", nghttp2_pq_top(&pq)) == 0);
  nghttp2_pq_pop(&pq);
  CU_ASSERT(3 == nghttp2_pq_size(&pq));
  CU_ASSERT(strcmp("bar", nghttp2_pq_top(&pq)) == 0);
  nghttp2_pq_pop(&pq);
  CU_ASSERT(strcmp("baz", nghttp2_pq_top(&pq)) == 0);
  nghttp2_pq_pop(&pq);
  CU_ASSERT(strcmp("foo", nghttp2_pq_top(&pq)) == 0);
  nghttp2_pq_pop(&pq);
  CU_ASSERT(nghttp2_pq_empty(&pq));
  CU_ASSERT(0 == nghttp2_pq_size(&pq));
  CU_ASSERT(NULL == nghttp2_pq_top(&pq));

  /* Add bunch of entry to see realloc works */
  for (i = 0; i < 10000; ++i) {
    CU_ASSERT(0 == nghttp2_pq_push(&pq, (void *)"foo"));
    CU_ASSERT((size_t)(i + 1) == nghttp2_pq_size(&pq));
  }
  for (i = 10000; i > 0; --i) {
    CU_ASSERT(NULL != nghttp2_pq_top(&pq));
    nghttp2_pq_pop(&pq);
    CU_ASSERT((size_t)(i - 1) == nghttp2_pq_size(&pq));
  }

  nghttp2_pq_free(&pq);
}
예제 #5
0
static void check_queued(nghttp2_stream *stream) {
  nghttp2_stream *si;
  int queued;

  if (stream->queued) {
    if (!stream_subtree_active(stream)) {
      fprintf(stderr,
              "stream(%p)=%d, stream->queued == 1, but "
              "stream_active() == %d and nghttp2_pq_size(&stream->obq) = %zu\n",
              stream, stream->stream_id, stream_active(stream),
              nghttp2_pq_size(&stream->obq));
      assert(0);
    }
    if (!stream_active(stream)) {
      queued = 0;
      for (si = stream->dep_next; si; si = si->sib_next) {
        if (si->queued) {
          ++queued;
        }
      }
      if (queued == 0) {
        fprintf(stderr,
                "stream(%p)=%d, stream->queued == 1, and "
                "!stream_active(), but no descendants is queued\n",
                stream, stream->stream_id);
        assert(0);
      }
    }

    for (si = stream->dep_next; si; si = si->sib_next) {
      check_queued(si);
    }
  } else {
    if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) {
      fprintf(stderr,
              "stream(%p) = %d, stream->queued == 0, but "
              "stream_active(stream) == %d and "
              "nghttp2_pq_size(&stream->obq) = %zu\n",
              stream, stream->stream_id, stream_active(stream),
              nghttp2_pq_size(&stream->obq));
      assert(0);
    }
    for (si = stream->dep_next; si; si = si->sib_next) {
      ensure_inactive(si);
    }
  }
}
예제 #6
0
/*
 * Returns nonzero if |stream| or one of its descendants is active
 */
static int stream_subtree_active(nghttp2_stream *stream) {
  return stream_active(stream) || !nghttp2_pq_empty(&stream->obq);
}
예제 #7
0
void test_nghttp2_pq(void) {
  int i;
  nghttp2_pq pq;
  string_entry *top;

  nghttp2_pq_init(&pq, pq_less, nghttp2_mem_default());
  CU_ASSERT(nghttp2_pq_empty(&pq));
  CU_ASSERT(0 == nghttp2_pq_size(&pq));
  CU_ASSERT(0 == nghttp2_pq_push(&pq, &string_entry_new("foo")->ent));
  CU_ASSERT(0 == nghttp2_pq_empty(&pq));
  CU_ASSERT(1 == nghttp2_pq_size(&pq));
  top = (string_entry *)nghttp2_pq_top(&pq);
  CU_ASSERT(strcmp("foo", top->s) == 0);
  CU_ASSERT(0 == nghttp2_pq_push(&pq, &string_entry_new("bar")->ent));
  top = (string_entry *)nghttp2_pq_top(&pq);
  CU_ASSERT(strcmp("bar", top->s) == 0);
  CU_ASSERT(0 == nghttp2_pq_push(&pq, &string_entry_new("baz")->ent));
  top = (string_entry *)nghttp2_pq_top(&pq);
  CU_ASSERT(strcmp("bar", top->s) == 0);
  CU_ASSERT(0 == nghttp2_pq_push(&pq, &string_entry_new("C")->ent));
  CU_ASSERT(4 == nghttp2_pq_size(&pq));

  top = (string_entry *)nghttp2_pq_top(&pq);
  CU_ASSERT(strcmp("C", top->s) == 0);
  string_entry_del(top);
  nghttp2_pq_pop(&pq);

  CU_ASSERT(3 == nghttp2_pq_size(&pq));

  top = (string_entry *)nghttp2_pq_top(&pq);
  CU_ASSERT(strcmp("bar", top->s) == 0);
  nghttp2_pq_pop(&pq);
  string_entry_del(top);

  top = (string_entry *)nghttp2_pq_top(&pq);
  CU_ASSERT(strcmp("baz", top->s) == 0);
  nghttp2_pq_pop(&pq);
  string_entry_del(top);

  top = (string_entry *)nghttp2_pq_top(&pq);
  CU_ASSERT(strcmp("foo", top->s) == 0);
  nghttp2_pq_pop(&pq);
  string_entry_del(top);

  CU_ASSERT(nghttp2_pq_empty(&pq));
  CU_ASSERT(0 == nghttp2_pq_size(&pq));
  CU_ASSERT(NULL == nghttp2_pq_top(&pq));

  /* Add bunch of entry to see realloc works */
  for (i = 0; i < 10000; ++i) {
    CU_ASSERT(0 == nghttp2_pq_push(&pq, &string_entry_new("foo")->ent));
    CU_ASSERT((size_t)(i + 1) == nghttp2_pq_size(&pq));
  }
  for (i = 10000; i > 0; --i) {
    top = (string_entry *)nghttp2_pq_top(&pq);
    CU_ASSERT(NULL != top);
    nghttp2_pq_pop(&pq);
    string_entry_del(top);
    CU_ASSERT((size_t)(i - 1) == nghttp2_pq_size(&pq));
  }

  nghttp2_pq_free(&pq);
}