コード例 #1
0
ファイル: queue.test.c プロジェクト: edahlgren/nitro
int main(int argc, char **argv) {
    test_state tstate = {0};
    nitro_queue_t *q = nitro_queue_new(0, 
    test_state_callback, &tstate);
    TEST("new non-null", q);

    nitro_frame_t *hello = nitro_frame_new_copy(
        "hello", 6);

    nitro_queue_push(q, hello, 1);
    TEST("queue went contents", 
        tstate.got_state_change 
        && tstate.state_was == NITRO_QUEUE_STATE_CONTENTS);
    tstate.got_state_change = 0;

    nitro_frame_t *back = nitro_queue_pull(q, 1);
    TEST("got frame back", 
        back == hello);
    TEST("queue went empty", 
        tstate.got_state_change 
        && tstate.state_was == NITRO_QUEUE_STATE_EMPTY);
    tstate.got_state_change = 0;


    /* Ordering */
    nitro_frame_t *world = nitro_frame_new_copy(
        "world", 6);
    nitro_queue_push(q, hello, 1);
    nitro_queue_push(q, world, 1);

    back = nitro_queue_pull(q, 1);
    TEST("got hello (ordering)", 
        back == hello);
    back = nitro_queue_pull(q, 1);
    TEST("got world (ordering)", 
        back == world);

    nitro_queue_destroy(q);
    q = nitro_queue_new(0, 
    test_state_callback, &tstate);

    /* Wrapping */
    TEST("pre-wrapping empty queue", nitro_queue_count(q) == 0);
    TEST("pre-wrapping internal assumption", q->size == 1024);

    int i;
    for (i=0; i < 1023; i++) {
        nitro_frame_t *hcopy = nitro_frame_copy_partial(hello, NULL);
        nitro_queue_push(q, hcopy, 1);
        back = nitro_queue_pull(q, 1);
        assert(back == hcopy);
        nitro_frame_destroy(back);
    }


    nitro_queue_push(q, hello, 1);
    nitro_queue_push(q, world, 1);

    TEST("wrapping internals, wrap occurred",
    q->tail < q->head);

    back = nitro_queue_pull(q, 1);
    TEST("got hello (wrapping)", 
        back == hello);
    back = nitro_queue_pull(q, 1);
    TEST("got world (wrapping)", 
        back == world);

    TEST("wrapping internals, wrap back to even",
    q->tail == q->head);

    /* Destroy with frames in */

    my_frame_data dt = {0};

    nitro_frame_destroy(world);
    world = nitro_frame_new(
    "hello", 6, my_free, &dt);

    nitro_queue_push(q, world, 1);

    TEST("delete outstanding.. not deleted",
    dt.done == 0);

    nitro_queue_destroy(q);

    TEST("post-queue-delete.. frame free",
    dt.done);

    nitro_frame_destroy(hello);

    /* Queue count */

    q = nitro_queue_new(0,
    test_state_callback, &tstate);

    hello = nitro_frame_new_copy("hello", 6);

    for (i=0; i < 313; i++) {
        back = nitro_frame_copy_partial(hello, NULL);
        nitro_queue_push(q, back, 1);
    }

    nitro_frame_destroy(hello);


    TEST("count basic", nitro_queue_count(q) == 313);

    /* resize */
    nitro_queue_destroy(q);
    q = nitro_queue_new(0,
    test_state_callback, &tstate);
    assert(q->size == 1024);

    /* get the alignment off */
    for (i=0; i < 100; i++) {
        nitro_queue_push(q,
            nitro_frame_new_copy((void*)&i, sizeof(int)), 1);
    }

    for (i=0; i < 100; i++) {
        back = nitro_queue_pull(q, 1);
        nitro_frame_destroy(back);
    }

    TEST("resize misalign reset", nitro_queue_count(q) == 0 &&
    q->head > q->q);

    /* okay, now cause resize */
    for (i=0; i < 1050; i++) {
        nitro_queue_push(q,
            nitro_frame_new_copy((void*)&i, sizeof(int)), 1);
    }

    TEST("was resized", q->size > 1024);

    for (i=0; i < 1050; i++) {
        back = nitro_queue_pull(q, 1);
        if ( *((int*)nitro_frame_data(back)) != i)
            break;
        nitro_frame_destroy(back);
    }

    TEST("order after resize", i == 1050);

    nitro_queue_destroy(q);

    /* Test queue moving */

    /* move 0 -> 0 */
    q = nitro_queue_new(0,
    test_state_callback, &tstate);
    nitro_queue_t *dst = nitro_queue_new(0,
    test_state_callback, &tstate);

    nitro_queue_move(
    q, dst);
    TEST("move(0->0) src empty",
    nitro_queue_count(q) == 0);
    TEST("move(0->0) dest empty",
    nitro_queue_count(dst) == 0);

    /* move N -> 0 */

    for (i=0; i < 5; i++) {
        nitro_queue_push(q,
            nitro_frame_new_copy(
            (void *)&i, sizeof(int)), 1);
    }

    TEST("load 5 into src",
    nitro_queue_count(q) == 5);
    nitro_queue_move(q, dst);
    TEST("move(0->0) src empty",
    nitro_queue_count(q) == 0);
    TEST("move(0->0) dest 5",
    nitro_queue_count(dst) == 5);

    for (i=0; i < 5; i++) {
        back = nitro_queue_pull(dst, 1);
        if ( *((int*)nitro_frame_data(back)) != i)
            break;
        nitro_frame_destroy(back);
    }

    TEST("order after move", i == 5);

    nitro_queue_destroy(q);
    nitro_queue_destroy(dst);

    /* move with fractional wraparound, ugly copies */
    q = nitro_queue_new(0,
    test_state_callback, &tstate);
    dst = nitro_queue_new(0,
    test_state_callback, &tstate);

    for (i=0; i < 300; i++) {
        nitro_queue_push(q,
            nitro_frame_new_copy(
            (void *)&i, sizeof(int)), 1);
    }
    for (i=0; i < 300; i++) {
        nitro_frame_destroy(nitro_queue_pull(q, 1));
    }
    for (i=0; i < 700; i++) {
        nitro_queue_push(q,
            nitro_frame_new_copy(
            (void *)&i, sizeof(int)), 1);
    }

    for (i=0; i < 324; i++) {
        nitro_queue_push(dst,
            nitro_frame_new_copy(
            (void *)&i, sizeof(int)), 1);
    }
    for (i=0; i < 324; i++) {
        nitro_frame_destroy(nitro_queue_pull(dst, 1));
    }
    for (i=0; i < 324; i++) {
        nitro_queue_push(dst,
            nitro_frame_new_copy(
            (void *)&i, sizeof(int)), 1);
    }

    TEST("(ugly move) count 700 src",
    nitro_queue_count(q) == 700);
    TEST("(ugly move) count 324 dst",
    nitro_queue_count(dst) == 324);

    nitro_queue_move(q, dst);
    TEST("(ugly move post) count 0 src",
    nitro_queue_count(q) == 0);
    TEST("(ugly move post) count 1024 dst",
    nitro_queue_count(dst) == 1024);
    assert(dst->size == 1024); /* no resizing! */
    TEST("(ugly move post) head == tail",
    dst->head == dst->tail);

    for (i=0; i < 324; i++) {
        back = nitro_queue_pull(dst, 1);
        if ( *((int*)nitro_frame_data(back)) != i)
            break;
        nitro_frame_destroy(back);
    }
    TEST("(ugly move post) first 324 still there",
    i == 324);
    for (i=0; i < 700; i++) {
        back = nitro_queue_pull(dst, 1);
        if ( *((int*)nitro_frame_data(back)) != i)
            break;
        nitro_frame_destroy(back);
    }
    TEST("(ugly move post) appended 700 there",
    i == 700);
    TEST("(ugly move post) dst emptied",
    nitro_queue_count(dst) == 0);

    nitro_queue_destroy(q);
    nitro_queue_destroy(dst);

    /* move with resize */
    q = nitro_queue_new(0,
    test_state_callback, &tstate);
    dst = nitro_queue_new(0,
    test_state_callback, &tstate);

    for (i=0; i < 1000; i++) {
        nitro_queue_push(q,
            nitro_frame_new_copy(
            (void *)&i, sizeof(int)), 1);
    }

    for (i=0; i < 324; i++) {
        nitro_queue_push(dst,
            nitro_frame_new_copy(
            (void *)&i, sizeof(int)), 1);
    }

    TEST("(resize move) count 1000 src",
    nitro_queue_count(q) == 1000);
    TEST("(resize move) count 324 dst",
    nitro_queue_count(dst) == 324);
    assert(dst->size == 1024);
    nitro_queue_move(q, dst);
    TEST("(resize post-move) size dst is sum",
    nitro_queue_count(dst) == 1324);
    assert(dst->size > 1024);

    for (i=0; i < 324; i++) {
        back = nitro_queue_pull(dst, 1);
        if ( *((int*)nitro_frame_data(back)) != i)
            break;
        nitro_frame_destroy(back);
    }
    TEST("(resize post-move) first 324 still there",
    i == 324);
    for (i=0; i < 1000; i++) {
        back = nitro_queue_pull(dst, 1);
        if ( *((int*)nitro_frame_data(back)) != i)
            break;
        nitro_frame_destroy(back);
    }
    TEST("(resize post-move) appended 1000 there",
    i == 1000);
    TEST("(resize post-move) dst cleared",
    nitro_queue_count(dst) == 0);

    nitro_queue_destroy(q);
    nitro_queue_destroy(dst);

    /* Capacity tests */

    q = nitro_queue_new(5,
    test_state_callback, &tstate);

    for (i=0; i < 5; i++) {
        nitro_queue_push(q,
            nitro_frame_new_copy(
            (void *)&i, sizeof(int)), 1);
    }

    double d1 = now_double();
    pthread_t t1;
    pthread_create(&t1, NULL, take_item, (void*)q);
    nitro_queue_push(q,
        nitro_frame_new_copy(
        (void *)&i, sizeof(int)), 1);
    double d2 = now_double();
    TEST("(capacity) got blocked on push",
    (d2 - d1 > 0.7) && (d2 - d1 < 1.5));

    for (i=1; i < 6; i++) {
        back = nitro_queue_pull(q, 1);
        if ( *((int*)nitro_frame_data(back)) != i)
            break;
        nitro_frame_destroy(back);
    }
    TEST("(capacity) have rest",
    i == 6);
    TEST("(capacity) emptied",
    nitro_queue_count(q) == 0);
    pthread_t t2;

    d1 = now_double();
    pthread_create(&t2, NULL, put_item, (void*)q);
    back = nitro_queue_pull(q, 1);
    d2 = now_double();
    TEST("(capacity) got blocked on empty pull",
    (d2 - d1 > 0.7) && (d2 - d1 < 1.5));
    TEST("(capacity) empty pull got right frame",
    *((int*)nitro_frame_data(back)) == 1337);
    nitro_frame_destroy(back);

    nitro_queue_destroy(q);

    void *unused;
    pthread_join(t1, &unused);
    pthread_join(t2, &unused);


    /* Consume */
    q = nitro_queue_new(0,
    test_state_callback, &tstate);

    gframe = nitro_frame_new_copy("hello", 6);

    /* Traditional test */
    d1 = now_double();
    for (i=0; i < CONSUME_COUNT; i++) {
        nitro_queue_push(q,
            nitro_frame_copy_partial(gframe, NULL), 1);
    }
    d2 = now_double();

    char buf[50];
    snprintf(buf, 50, "(consume-manual) in %.4f",
    d2 - d1);
    TEST(buf, nitro_queue_count(q) == CONSUME_COUNT);
    nitro_queue_destroy(q);

    // vs consume
    i = 0;
    q = nitro_queue_new(0,
    test_state_callback, &tstate);
    d1 = now_double();
    nitro_queue_consume(q,
        make_frames, (void *)&i);
    d2 = now_double();
    snprintf(buf, 50, "(consume-stream) in %.4f",
    d2 - d1);
    TEST(buf, nitro_queue_count(q) == CONSUME_COUNT);
    nitro_queue_destroy(q);

    nitro_frame_destroy(gframe);

    /* Write to file */

    q = nitro_queue_new(0,
    test_state_callback, &tstate);
    for (i=0; i < 50000; i++) {
        nitro_queue_push(q,
            nitro_frame_new_copy(
                "dog", 3), 1);
    }

    int ps[2];
    int r = pipe(ps);
    assert(!r);

    int pread = ps[0];
    int pwrite = ps[1];

    int flag = 1;
    r = ioctl(pread, FIONBIO, &flag);
    assert(r == 0);
    r = ioctl(pwrite, FIONBIO, &flag);
    assert(r == 0);

    int bytes = 0;
    int total = 0;
    nitro_frame_t *remain = NULL;
    pthread_t reader;
    char out[550000];
    pipe_pass pp = {out, pread};
    pthread_create(&reader, NULL, pipe_consume, &pp);
    do {
        errno = 0;
        if (bytes > 0)
            total += bytes;
        bytes = nitro_queue_fd_write(
            q, pwrite, remain, &remain);
    } while (bytes > 0 || errno == EAGAIN || errno == EWOULDBLOCK);
    if (bytes < 0) {
        perror("write to pipe:");
        assert(bytes == 0);
    }

    TEST("(fd write) correct write byte count",
    total == 550000);

    void *t_ret;
    /* wait for reader to finish */
    pthread_join(reader, &t_ret);

    char *ptr = out;
    nitro_protocol_header target_head = {
        1,
        0,
        0,
        0,
        3};

    for (i=0; i < 50000; i++) {
        if (memcmp(ptr, &target_head, sizeof(target_head)) ||
            memcmp(ptr + sizeof(target_head), "dog", 3)) {
            break;
        }
        ptr += 11;
    }

    TEST("(fd write) read data was correct",
    ptr == out + 550000);

    close(pwrite);
    close(pread);


    nitro_queue_destroy(q);

    SUMMARY(0);
    return 1;
}
コード例 #2
0
ファイル: Sinproc.c プロジェクト: bumptech/nitro
/* Sinproc_create_queues
 * ------------------
 *
 * Create the global in queue associated with a socket
 */
void Sinproc_create_queues(nitro_inproc_socket_t *s) {
    s->q_recv = nitro_queue_new(
                    s->opt->hwm_in, Sinproc_socket_recv_queue_stat, (void *)s);
}