Exemple #1
0
int main() {
    /* Test 'msleep'. */
    int64_t deadline = now() + 100;
    int rc = msleep(deadline);
    errno_assert(rc == 0);
    int64_t diff = now () - deadline;
    time_assert(diff, 0);

    /* msleep-sort */
    int ch = chmake(sizeof(int));
    errno_assert(ch >= 0);
    int hndls[4];
    hndls[0] = go(delay(30, ch));
    errno_assert(hndls[0] >= 0);
    hndls[1] = go(delay(40, ch));
    errno_assert(hndls[1] >= 0);
    hndls[2] = go(delay(10, ch));
    errno_assert(hndls[2] >= 0);
    hndls[3] = go(delay(20, ch));
    errno_assert(hndls[3] >= 0);
    int val;
    rc = chrecv(ch, &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 10);
    rc = chrecv(ch, &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 20);
    rc = chrecv(ch, &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 30);
    rc = chrecv(ch, &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 40);
    rc = hclose(hndls[0]);
    errno_assert(rc == 0);
    rc = hclose(hndls[1]);
    errno_assert(rc == 0);
    rc = hclose(hndls[2]);
    errno_assert(rc == 0);
    rc = hclose(hndls[3]);
    errno_assert(rc == 0);
    rc = hclose(ch);
    errno_assert(rc == 0);

    return 0;
}
Exemple #2
0
int main() {
    int rc;

    /* Check invalid fd. */
    rc = fdin(33, -1);
    assert(rc == -1 && errno == EBADF);
    rc = fdout(33, -1);
    assert(rc == -1 && errno == EBADF);

    /* Create a pair of file deshndliptors for testing. */
    int fds[2];
    rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
    errno_assert(rc == 0);

    /* Check for in & out. */
    rc = fdout(fds[0], 0);
    errno_assert(rc == 0);
    rc = fdin(fds[0], 0);
    assert(rc == -1 && errno == ETIMEDOUT);

    /* Check with infinite timeout. */
    rc = fdout(fds[0], -1);
    errno_assert(rc == 0);

    /* Check with the timeout that doesn't expire. */
    rc = fdout(fds[0], now() + 100);
    errno_assert(rc == 0);

    /* Check with the timeout that does expire. */
    int64_t deadline = now() + 100;
    rc = fdin(fds[0], deadline);
    assert(rc == -1 && errno == ETIMEDOUT);
    int64_t diff = now() - deadline;
    time_assert(diff, 0);

    /* Check cancelation. */
    int hndl1 = go(cancel(fds[0]));
    errno_assert(hndl1 >= 0);
    rc = hclose(hndl1);
    errno_assert(rc == 0);

    /* Check for in. */
    ssize_t sz = send(fds[1], "A", 1, 0);
    errno_assert(sz == 1);
    rc = fdin(fds[0], -1);
    errno_assert(rc == 0);
    char c;
    sz = recv(fds[0], &c, 1, 0);
    errno_assert(sz == 1);

    /* Two interleaved deadlines. */
    int64_t start = now();
    int hndl2 = go(trigger(fds[0], start + 50));
    errno_assert(hndl2 >= 0);
    rc = fdin(fds[1], start + 90);
    errno_assert(rc == 0);
    diff = now() - start;
    time_assert(diff, 50);
    rc = hclose(hndl2);
    errno_assert(rc == 0);

    /* Check whether closing the connection is reported. */
    ssize_t nbytes = send(fds[1], "ABC", 3, 0);
    errno_assert(nbytes == 3);
    rc = fdclean(fds[1]);
    errno_assert(rc == 0);
    rc = close(fds[1]);
    errno_assert(rc == 0);
    rc = msleep(now() + 50);
    errno_assert(rc == 0);
    rc = fdin(fds[0], -1);
    errno_assert(rc == 0);
    rc = fdout(fds[0], -1);
    errno_assert(rc == 0);
    char buf[10];
    nbytes = recv(fds[0], buf, sizeof(buf), 0);
    assert(nbytes == 3);
    rc = fdin(fds[0], -1);
    errno_assert(rc == 0);
    nbytes = recv(fds[0], buf, sizeof(buf), 0);
    assert(nbytes == 0 || (nbytes == -1 && errno == ECONNRESET));
    rc = fdclean(fds[0]);
    errno_assert(rc == 0);
    rc = close(fds[0]);
    errno_assert(rc == 0);

    /* Test whether fd is removed from the pollset after fdin/fdout times
       out. */
    int pp[2];
    rc = pipe(pp);
    assert(rc == 0);
    rc = fdin(pp[0], now() + 10);
    assert(rc == -1 && errno == ETIMEDOUT);
    nbytes = write(pp[1], "ABC", 3);
    assert(nbytes == 3);
    rc = msleep(now() + 100);
    assert(rc == 0);
    rc = fdclean(pp[0]);
    errno_assert(rc == 0);
    rc = fdclean(pp[1]);
    errno_assert(rc == 0);
    rc = close(pp[0]);
    assert(rc == 0);
    rc = close(pp[1]);
    assert(rc == 0);

    return 0;
}
Exemple #3
0
int main() {
    int rc;
    int val;

    /* Non-blocking receiver case. */
    int ch1 = chmake(sizeof(int));
    errno_assert(ch1 >= 0);
    int hndl1 = go(sender1(ch1, 555));
    errno_assert(hndl1 >= 0);
    struct chclause cls1[] = {{CHRECV, ch1, &val, sizeof(val)}};
    rc = choose(cls1, 1, -1);
    choose_assert(0, 0);
    assert(val == 555);
    hclose(ch1);
    rc = hclose(hndl1);
    errno_assert(rc == 0);

    /* Blocking receiver case. */
    int ch2 = chmake(sizeof(int));
    errno_assert(ch2 >= 0);
    int hndl2 = go(sender2(ch2, 666));
    errno_assert(hndl2 >= 0);
    struct chclause cls2[] = {{CHRECV, ch2, &val, sizeof(val)}};
    rc = choose(cls2, 1, -1);
    choose_assert(0, 0);
    assert(val == 666);
    hclose(ch2);
    rc = hclose(hndl2);
    errno_assert(rc == 0);

    /* Non-blocking sender case. */
    int ch3 = chmake(sizeof(int));
    errno_assert(ch3 >= 0);
    int hndl3 = go(receiver1(ch3, 777));
    errno_assert(hndl3 >= 0);
    val = 777;
    struct chclause cls3[] = {{CHSEND, ch3, &val, sizeof(val)}};
    rc = choose(cls3, 1, -1);
    choose_assert(0, 0);
    hclose(ch3);
    rc = hclose(hndl3);
    errno_assert(rc == 0);

    /* Blocking sender case. */
    int ch4 = chmake(sizeof(int));
    errno_assert(ch4 >= 0);
    int hndl4 = go(receiver2(ch4, 888));
    errno_assert(hndl4 >= 0);
    val = 888;
    struct chclause cls4[] = {{CHSEND, ch4, &val, sizeof(val)}};
    rc = choose(cls4, 1, -1);
    choose_assert(0, 0);
    hclose(ch4);
    rc = hclose(hndl4);
    errno_assert(rc == 0);

    /* Check with two channels. */
    int hndl5[2];
    int ch5 = chmake(sizeof(int));
    errno_assert(ch5 >= 0);
    int ch6 = chmake(sizeof(int));
    errno_assert(ch6 >= 0);
    hndl5[0] = go(sender1(ch6, 555));
    errno_assert(hndl5 >= 0);
    struct chclause cls5[] = {
        {CHRECV, ch5, &val, sizeof(val)},
        {CHRECV, ch6, &val, sizeof(val)}
    };
    rc = choose(cls5, 2, -1);
    choose_assert(1, 0);
    assert(val == 555);
    hndl5[1] = go(sender2(ch5, 666));
    errno_assert(hndl5 >= 0);
    rc = choose(cls5, 2, -1);
    choose_assert(0, 0);
    assert(val == 666);
    hclose(ch5);
    hclose(ch6);
    rc = hclose(hndl5[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl5[1]);
    errno_assert(rc == 0);

    /* Test whether selection of in channels is random. */
    int ch7 = chmake(sizeof(int));
    errno_assert(ch7 >= 0);
    int ch8 = chmake(sizeof(int));
    errno_assert(ch8 >= 0);
    int hndl6[2];
    hndl6[0] = go(feeder(ch7, 111));
    errno_assert(hndl6[0] >= 0);
    hndl6[1] = go(feeder(ch8, 222));
    errno_assert(hndl6[1] >= 0);
    int i;
    int first = 0;
    int second = 0;
    int third = 0;
    for(i = 0; i != 100; ++i) {
        struct chclause cls6[] = {
            {CHRECV, ch7, &val, sizeof(val)},
            {CHRECV, ch8, &val, sizeof(val)}
        };
        rc = choose(cls6, 2, -1);
        errno_assert(rc == 0 || rc == 1);
        if(rc == 0) {
            assert(val == 111);
            ++first;
        }
        if(rc == 1) {
            assert(val == 222);
            ++second;
        }
        int rc = yield();
        errno_assert(rc == 0);
    }
    assert(first > 1 && second > 1);
    hclose(hndl6[0]);
    hclose(hndl6[1]);
    hclose(ch7);
    hclose(ch8);

    /* Test 'otherwise' clause. */
    int ch9 = chmake(sizeof(int));
    errno_assert(ch9 >= 0);
    struct chclause cls7[] = {{CHRECV, ch9, &val, sizeof(val)}};
    rc = choose(cls7, 1, 0);
    choose_assert(-1, ETIMEDOUT);
    hclose(ch9);
    rc = choose(NULL, 0, 0);
    choose_assert(-1, ETIMEDOUT);

    /* Test two simultaneous senders vs. choose statement. */
    int ch10 = chmake(sizeof(int));
    errno_assert(ch10 >= 0);
    int hndl7[2];
    hndl7[0] = go(sender1(ch10, 888));
    errno_assert(hndl7[0] >= 0);
    hndl7[1] = go(sender1(ch10, 999));
    errno_assert(hndl7[1] >= 0);
    val = 0;
    struct chclause cls8[] = {{CHRECV, ch10, &val, sizeof(val)}};
    rc = choose(cls8, 1, -1);
    choose_assert(0, 0);
    assert(val == 888);
    val = 0;
    rc = choose(cls8, 1, -1);
    choose_assert(0, 0);
    assert(val == 999);
    hclose(ch10);
    rc = hclose(hndl7[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl7[1]);
    errno_assert(rc == 0);

    /* Test two simultaneous receivers vs. choose statement. */
    int ch11 = chmake(sizeof(int));
    errno_assert(ch11 >= 0);
    int hndl8[2];
    hndl8[0] = go(receiver1(ch11, 333));
    errno_assert(hndl8[0] >= 0);
    hndl8[1] = go(receiver1(ch11, 444));
    errno_assert(hndl8[1] >= 0);
    val = 333;
    struct chclause cls9[] = {{CHSEND, ch11, &val, sizeof(val)}};
    rc = choose(cls9, 1, -1);
    choose_assert(0, 0);
    val = 444;
    rc = choose(cls9, 1, -1);
    choose_assert(0, 0);
    hclose(ch11);
    rc = hclose(hndl8[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl8[1]);
    errno_assert(rc == 0);

    /* Choose vs. choose. */
    int ch12 = chmake(sizeof(int));
    errno_assert(ch12 >= 0);
    int hndl9 = go(choosesender(ch12, 111));
    errno_assert(hndl9 >= 0);
    struct chclause cls10[] = {{CHRECV, ch12, &val, sizeof(val)}};
    rc = choose(cls10, 1, -1);
    choose_assert(0, 0);
    assert(val == 111);
    hclose(ch12);
    rc = hclose(hndl9);
    errno_assert(rc == 0);

    /* Test transferring a large object. */
    int ch17 = chmake(sizeof(struct large));
    errno_assert(ch17 >= 0);
    int hndl10 = go(sender4(ch17));
    errno_assert(hndl9 >= 0);
    struct large lrg;
    struct chclause cls14[] = {{CHRECV, ch17, &lrg, sizeof(lrg)}};
    rc = choose(cls14, 1, -1);
    choose_assert(0, 0);
    hclose(ch17);

    /* Test that 'in' on done-with channel fires. */
    int ch18 = chmake(sizeof(int));
    errno_assert(ch18 >= 0);
    rc = hdone(ch18);
    errno_assert(rc == 0);
    struct chclause cls15[] = {{CHRECV, ch18, &val, sizeof(val)}};
    rc = choose(cls15, 1, -1);
    choose_assert(0, EPIPE);
    hclose(ch18);

    /* Test expiration of 'deadline' clause. */
    int ch21 = chmake(sizeof(int));
    errno_assert(ch21 >= 0);
    int64_t start = now();
    struct chclause cls17[] = {{CHRECV, ch21, &val, sizeof(val)}};
    rc = choose(cls17, 1, start + 50);
    choose_assert(-1, ETIMEDOUT);
    int64_t diff = now() - start;
    time_assert(diff, 50);
    hclose(ch21);

    /* Test unexpired 'deadline' clause. */
    int ch22 = chmake(sizeof(int));
    errno_assert(ch22 >= 0);
    start = now();
    int hndl11 = go(sender3(ch22, 4444, start + 50));
    errno_assert(hndl11 >= 0);
    struct chclause cls18[] = {{CHRECV, ch22, &val, sizeof(val)}};
    rc = choose(cls17, 1, start + 1000);
    choose_assert(0, 0);
    assert(val == 4444);
    diff = now() - start;
    time_assert(diff, 50);
    hclose(ch22);
    rc = hclose(hndl11);
    errno_assert(rc == 0);

    /* Test that first channel in the array is prioritized. */
    int ch23 = chmake(sizeof(int));
    errno_assert(ch23 >= 0);
    int ch24 = chmake(sizeof(int));
    errno_assert(ch24 >= 0);
    int hndl12 = go(sender1(ch23, 0));
    errno_assert(hndl12 >= 0);
    int hndl13 = go(sender1(ch24, 0));
    errno_assert(hndl13 >= 0);
    struct chclause cls19[] = {
        {CHRECV, ch24, &val, sizeof(val)},
        {CHRECV, ch23, &val, sizeof(val)}
    };
    rc = choose(cls19, 2, -1);
    choose_assert(0, 0);
    rc = chrecv(ch23, &val, sizeof(val), -1);
    errno_assert(rc == 0);
    rc = hclose(hndl13);
    errno_assert(rc == 0);
    rc = hclose(hndl12);
    errno_assert(rc == 0);
    rc = hclose(ch24);
    errno_assert(rc == 0);
    rc = hclose(ch23);
    errno_assert(rc == 0);

    /* Try adding the same channel to choose twice. Doing so is pointless,
       but it shouldn't crash the application. */
    int ch25 = chmake(sizeof(int));
    errno_assert(ch25 >= 0);
    struct chclause cls20[] = {
        {CHRECV, ch25, &val, sizeof(val)},
        {CHRECV, ch25, &val, sizeof(val)}
    };
    rc = choose(cls20, 2, now() + 50);
    choose_assert(-1, ETIMEDOUT);
    rc = hclose(ch25);
    errno_assert(rc == 0);

    return 0;
}
Exemple #4
0
int XS_TEST_MAIN ()
{
    int rc;
    char buf [32];

    fprintf (stderr, "survey test running...\n");

    //  Create the basic infrastructure.
    void *ctx = xs_init ();
    assert (ctx);
    void *xsurveyor = xs_socket (ctx, XS_XSURVEYOR);
    assert (xsurveyor);
    rc = xs_bind (xsurveyor, "inproc://a");
    assert (rc != -1);
    void *xrespondent = xs_socket (ctx, XS_XRESPONDENT);
    assert (xrespondent);
    rc = xs_bind (xrespondent, "inproc://b");
    assert (rc != -1);
    void *surveyor = xs_socket (ctx, XS_SURVEYOR);
    assert (surveyor);
    rc = xs_connect (surveyor, "inproc://b");
    assert (rc != -1);
    void *respondent1 = xs_socket (ctx, XS_RESPONDENT);
    assert (respondent1);
    rc = xs_connect (respondent1, "inproc://a");
    assert (rc != -1);
    void *respondent2 = xs_socket (ctx, XS_RESPONDENT);
    assert (respondent2);
    rc = xs_connect (respondent2, "inproc://a");
    assert (rc != -1);

    //  Send the survey.
    rc = xs_send (surveyor, "ABC", 3, 0);
    assert (rc == 3);

    //  Forward the survey through the intermediate device.
    //  Survey consist of identity (4 bytes), survey ID (4 bytes) and the body.
    rc = xs_recv (xrespondent, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xsurveyor, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xrespondent, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xsurveyor, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xrespondent, buf, sizeof (buf), 0);
    assert (rc == 3);
    rc = xs_send (xsurveyor, buf, 3, 0);
    assert (rc == 3);

    //  Respondent 1 responds to the survey.
    rc = xs_recv (respondent1, buf, sizeof (buf), 0);
    assert (rc == 3);
    rc = xs_send (respondent1, "DE", 2, 0);
    assert (rc == 2);

    //  Forward the response through the intermediate device.
    rc = xs_recv (xsurveyor, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xrespondent, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xsurveyor, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xrespondent, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xsurveyor, buf, sizeof (buf), 0);
    assert (rc == 2);
    rc = xs_send (xrespondent, buf, 2, 0);
    assert (rc == 2);

    //  Surveyor gets the response.
    rc = xs_recv (surveyor, buf, sizeof (buf), 0);
    assert (rc == 2);

    //  Respondent 2 responds to the survey.
    rc = xs_recv (respondent2, buf, sizeof (buf), 0);
    assert (rc == 3);
    rc = xs_send (respondent2, "FGHI", 4, 0);
    assert (rc == 4);

    //  Forward the response through the intermediate device.
    rc = xs_recv (xsurveyor, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xrespondent, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xsurveyor, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xrespondent, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xsurveyor, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xrespondent, buf, 4, 0);
    assert (rc == 4);

    //  Surveyor gets the response.
    rc = xs_recv (surveyor, buf, sizeof (buf), 0);
    assert (rc == 4);

    //  Now let's test whether survey timeout works as expected.
    int timeout = 100;
    rc = xs_setsockopt (surveyor, XS_SURVEY_TIMEOUT, &timeout, sizeof (int));
    assert (rc == 0);
    rc = xs_send (surveyor, "ABC", 3, 0);
    assert (rc == 3);
    void *watch = xs_stopwatch_start ();
    rc = xs_recv (surveyor, buf, sizeof (buf), 0);
    assert (rc == - 1 && errno == EAGAIN);
    unsigned long elapsed = xs_stopwatch_stop (watch) / 1000;
    time_assert (elapsed, (unsigned long) timeout);

    //  Test whether responses for old surveys are discarded. First,
    //  initiate new survey.
    rc = xs_setsockopt (surveyor, XS_SURVEY_TIMEOUT, &timeout, sizeof (int));
    assert (rc == 0);
    rc = xs_send (surveyor, "DE", 2, 0);
    assert (rc == 2);

    //  Read, process and reply to the old survey.
    rc = xs_recv (xrespondent, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xrespondent, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xrespondent, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xrespondent, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xrespondent, buf, sizeof (buf), 0);
    assert (rc == 3);
    rc = xs_send (xrespondent, buf, 3, 0);
    assert (rc == 3);

    //  Read, process and reply to the new survey.
    rc = xs_recv (xrespondent, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xrespondent, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xrespondent, buf, sizeof (buf), 0);
    assert (rc == 4);
    rc = xs_send (xrespondent, buf, 4, XS_SNDMORE);
    assert (rc == 4);
    rc = xs_recv (xrespondent, buf, sizeof (buf), 0);
    assert (rc == 2);
    rc = xs_send (xrespondent, buf, 2, 0);
    assert (rc == 2);

    //  Get the response and check it's the response to the new survey and
    //  that response to the old survey was silently discarded.
    rc = xs_recv (surveyor, buf, sizeof (buf), 0);
    assert (rc == 2);

    rc = xs_close (respondent2);
    assert (rc == 0);
    rc = xs_close (respondent1);
    assert (rc == 0);
    rc = xs_close (surveyor);
    assert (rc == 0);
    rc = xs_close (xrespondent);
    assert (rc == 0);
    rc = xs_close (xsurveyor);
    assert (rc == 0);
    rc = xs_term (ctx);
    assert (rc == 0);
    
    return 0 ;
}