Пример #1
0
static coroutine void sf_iworker(struct sf *conn) {
    struct msg msg = {NULL, 0};
    while(1) {
        uint64_t hdr;
        int rc = brecv(conn->u, &hdr, sizeof(hdr), -1);
        CHECKRC(ires)
        if(dill_slow(hdr == sf_termsequence)) {conn->ires = SF_DONE; break;}
        msg.len = (size_t)dill_getll((uint8_t*)&hdr);
        msg.buf = malloc(msg.len);
        dill_assert(msg.buf);
        rc = brecv(conn->u, msg.buf, msg.len, -1);
        CHECKRC(ires)
        rc = chsend(conn->ichan, &msg, sizeof(msg), -1);
        if(dill_slow(rc < 0 && errno == ECANCELED)) break;
        dill_assert(rc == 0);
        msg.buf = NULL;
        msg.len = 0;
    }
    free(msg.buf);
    int rc = chdone(conn->ichan);
    dill_assert(rc == 0);
}
Пример #2
0
static coroutine void sf_oworker(struct sf *conn) {
    struct msg msg = {NULL, 0};
    while(1) {
        int rc = chrecv(conn->ochan, &msg, sizeof(msg), -1);
        if(dill_slow(rc < 0 && errno == ECANCELED)) break;
        dill_assert(rc == 0);
        /* User requests that the coroutine stops. */
        if(!msg.buf) {conn->ores = SF_DONE; break;}
        uint64_t hdr;
        dill_putll((uint8_t*)&hdr, msg.len);
        rc = bsend(conn->u, &hdr, sizeof(hdr), -1);
        CHECKRC(ores)
        rc = bsend(conn->u, msg.buf, msg.len, -1);
        CHECKRC(ores)
        free(msg.buf);
        msg.buf = NULL;
        msg.len = 0;
        rc = bflush(conn->u, -1);
        CHECKRC(ores)
    }
    free(msg.buf);
    int rc = chdone(conn->ochan);
    dill_assert(rc == 0);
}
Пример #3
0
int main() {
    int val;
    int rc;

    /* Receiver waits for sender. */
    int ch1[2];
    rc = chmake(ch1);
    errno_assert(rc == 0);
    assert(ch1[0] >= 0);
    assert(ch1[1] >= 0);
    int hndl1 = go(sender(ch1[0], 1, 333));
    errno_assert(hndl1 >= 0);
    rc = chrecv(ch1[1], &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 333);
    rc = hclose(ch1[1]);
    errno_assert(rc == 0);
    rc = hclose(ch1[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl1);
    errno_assert(rc == 0);

    /* Sender waits for receiver. */
    int ch2[2];
    rc = chmake(ch2);
    errno_assert(rc == 0);
    int hndl2 = go(sender(ch2[0], 0, 444));
    errno_assert(hndl2 >= 0);
    rc = chrecv(ch2[1], &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 444);
    rc = hclose(ch2[1]);
    errno_assert(rc == 0);
    rc = hclose(ch2[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl2);
    errno_assert(rc == 0);

    /* Test two simultaneous senders. */
    int ch3[2];
    rc = chmake(ch3);
    errno_assert(rc == 0);
    int hndl3[2];
    hndl3[0] = go(sender(ch3[0], 0, 888));
    errno_assert(hndl3[0] >= 0);
    hndl3[1] = go(sender(ch3[0], 0, 999));
    errno_assert(hndl3[1] >= 0);
    rc = chrecv(ch3[1], &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 888);
    rc = yield();
    errno_assert(rc == 0);
    rc = chrecv(ch3[1], &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 999);
    rc = hclose(ch3[1]);
    errno_assert(rc == 0);
    rc = hclose(ch3[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl3[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl3[1]);
    errno_assert(rc == 0);

    /* Test two simultaneous receivers. */
    int ch4[2];
    rc = chmake(ch4);
    errno_assert(rc == 0);
    int hndl4[2];
    hndl4[0] = go(receiver(ch4[0], 333));
    errno_assert(hndl4[0] >= 0);
    hndl4[1] = go(receiver(ch4[0], 444));
    errno_assert(hndl4[1] >= 0);
    val = 333;
    rc = chsend(ch4[1], &val, sizeof(val), -1);
    errno_assert(rc == 0);
    val = 444;
    rc = chsend(ch4[1], &val, sizeof(val), -1);
    errno_assert(rc == 0);
    rc = hclose(ch4[1]);
    errno_assert(rc == 0);
    rc = hclose(ch4[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl4[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl4[1]);
    errno_assert(rc == 0);

    /* Test simple chdone() scenario. */
    int ch8[2];
    rc = chmake(ch8);
    errno_assert(rc == 0);
    rc = chdone(ch8[0]);
    errno_assert(rc == 0);
    rc = chrecv(ch8[1], &val, sizeof(val), -1);
    errno_assert(rc == -1 && errno == EPIPE);
    rc = chrecv(ch8[1], &val, sizeof(val), -1);
    errno_assert(rc == -1 && errno == EPIPE);
    rc = chrecv(ch8[1], &val, sizeof(val), -1);
    errno_assert(rc == -1 && errno == EPIPE);
    rc = hclose(ch8[1]);
    errno_assert(rc == 0);
    rc = hclose(ch8[0]);
    errno_assert(rc == 0);

    /* Test whether chdone() unblocks all receivers. */
    int ch12[2];
    rc = chmake(ch12);
    errno_assert(rc == 0);
    int hndl6[2];
    hndl6[0] = go(receiver2(ch12[0]));
    errno_assert(hndl6[0] >= 0);
    hndl6[1] = go(receiver2(ch12[0]));
    errno_assert(hndl6[1] >= 0);
    rc = chdone(ch12[1]);
    errno_assert(rc == 0);
    rc = chrecv(ch12[1], &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 0);
    rc = chrecv(ch12[1], &val, sizeof(val), -1);
    errno_assert(rc == 0);
    assert(val == 0);
    rc = hclose(ch12[1]);
    errno_assert(rc == 0);
    rc = hclose(ch12[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl6[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl6[1]);
    errno_assert(rc == 0);

    /* Test whether chdone() unblocks blocked senders. */
    int ch15[2];
    rc = chmake(ch15);
    errno_assert(rc == 0);
    int hndl8[3];
    hndl8[0] = go(sender2(ch15[0]));
    errno_assert(hndl8[0] >= 0);
    hndl8[1] = go(sender2(ch15[0]));
    errno_assert(hndl8[1] >= 0);
    hndl8[2] = go(sender2(ch15[0]));
    errno_assert(hndl8[2] >= 0);
    rc = msleep(now() + 50);
    errno_assert(rc == 0);
    rc = chdone(ch15[1]);
    errno_assert(rc == 0);
    rc = hclose(ch15[1]);
    errno_assert(rc == 0);
    rc = hclose(ch15[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl8[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl8[1]);
    errno_assert(rc == 0);
    rc = hclose(hndl8[2]);
    errno_assert(rc == 0);

    /* Test whether hclose() unblocks blocked senders and receivers. */
    int ch16[2];
    rc = chmake(ch16);
    errno_assert(rc == 0);
    int hndl9[2];
    hndl9[0] = go(receiver3(ch16[0]));
    errno_assert(hndl9[0] >= 0);
    hndl9[1] = go(receiver3(ch16[0]));
    errno_assert(hndl9[1] >= 0);
    rc = msleep(now() + 50);
    errno_assert(rc == 0);
    rc = hclose(ch16[1]);
    errno_assert(rc == 0);
    rc = hclose(ch16[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl9[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl9[1]);
    errno_assert(rc == 0);

    /* Test cancelation. */
    int ch17[2];
    rc = chmake(ch17);
    errno_assert(rc == 0);
    int hndl10 = go(cancel(ch17[0]));
    errno_assert(hndl10 >= 0);
    rc = hclose(hndl10);
    errno_assert(rc == 0);
    rc = hclose(ch17[1]);
    errno_assert(rc == 0);
    rc = hclose(ch17[0]);
    errno_assert(rc == 0);

    /* Receiver waits for sender (zero-byte message). */
    int ch18[2];
    rc = chmake(ch18);
    errno_assert(rc == 0);
    int hndl11 = go(sender3(ch18[0], 1));
    errno_assert(hndl11 >= 0);
    rc = chrecv(ch18[1], NULL, 0, -1);
    errno_assert(rc == 0);
    rc = hclose(ch18[1]);
    errno_assert(rc == 0);
    rc = hclose(ch18[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl11);
    errno_assert(rc == 0);

    /* Sender waits for receiver (zero-byte message). */
    int ch19[2];
    rc = chmake(ch19);
    errno_assert(rc == 0);
    int hndl12 = go(sender3(ch19[0], 0));
    errno_assert(hndl12 >= 0);
    rc = chrecv(ch19[1], NULL, 0, -1);
    errno_assert(rc == 0);
    rc = hclose(ch19[1]);
    errno_assert(rc == 0);
    rc = hclose(ch19[0]);
    errno_assert(rc == 0);
    rc = hclose(hndl12);
    errno_assert(rc == 0);

    /* Channel with user-supplied storage. */
    struct chstorage mem;
    int ch20[2];
    rc = chmake_mem(&mem, ch20);
    errno_assert(rc == 0);
    rc = chrecv(ch20[0], NULL, 0, now() + 50);
    errno_assert(rc == -1 && errno == ETIMEDOUT);
    rc = hclose(ch20[1]);
    errno_assert(rc == 0);
    rc = hclose(ch20[0]);
    errno_assert(rc == 0);

    return 0;
}