コード例 #1
0
ファイル: reqrep_ipc.cpp プロジェクト: PiotrSikora/libxs
int XS_TEST_MAIN ()
{
    fprintf (stderr, "reqrep_ipc test running...\n");

    void *ctx = xs_init ();
    assert (ctx);

    void *sb = xs_socket (ctx, XS_REP);
    assert (sb);
    int rc = xs_bind (sb, "ipc:///tmp/tester");
    assert (rc == 0);

    void *sc = xs_socket (ctx, XS_REQ);
    assert (sc);
    rc = xs_connect (sc, "ipc:///tmp/tester");
    assert (rc == 0);
    
    bounce (sb, sc);

    rc = xs_close (sc);
    assert (rc == 0);

    rc = xs_close (sb);
    assert (rc == 0);

    rc = xs_term (ctx);
    assert (rc == 0);

    return 0 ;
}
コード例 #2
0
ファイル: pair_tcp.cpp プロジェクト: PiotrSikora/libxs
int XS_TEST_MAIN ()
{
    fprintf (stderr, "pair_tcp test running...\n");

    void *ctx = xs_init ();
    assert (ctx);

    void *sb = xs_socket (ctx, XS_PAIR);
    assert (sb);
    int rc = xs_bind (sb, "tcp://127.0.0.1:5560");
    assert (rc == 0);

    void *sc = xs_socket (ctx, XS_PAIR);
    assert (sc);
    rc = xs_connect (sc, "tcp://127.0.0.1:5560");
    assert (rc == 0);
    
    bounce (sb, sc);

    rc = xs_close (sc);
    assert (rc == 0);

    rc = xs_close (sb);
    assert (rc == 0);

    rc = xs_term (ctx);
    assert (rc == 0);

    return 0 ;
}
コード例 #3
0
ファイル: hwm.cpp プロジェクト: paulbalomiri/libxs
int XS_TEST_MAIN ()
{
    fprintf (stderr, "hwm test running...\n");

    void *ctx = xs_init ();
    assert (ctx);

    //  Create pair of socket, each with high watermark of 2. Thus the total
    //  buffer space should be 4 messages.
    void *sb = xs_socket (ctx, XS_PULL);
    assert (sb);
    int hwm = 2;
    int rc = xs_setsockopt (sb, XS_RCVHWM, &hwm, sizeof (hwm));
    assert (rc == 0);
    rc = xs_bind (sb, "inproc://a");
    assert (rc != -1);

    void *sc = xs_socket (ctx, XS_PUSH);
    assert (sc);
    rc = xs_setsockopt (sc, XS_SNDHWM, &hwm, sizeof (hwm));
    assert (rc == 0);
    rc = xs_connect (sc, "inproc://a");
    assert (rc != -1);

    //  Try to send 10 messages. Only 4 should succeed.
    for (int i = 0; i < 10; i++)
    {
        rc = xs_send (sc, NULL, 0, XS_DONTWAIT);
        if (i < 4)
            assert (rc == 0);
        else
            assert (rc < 0 && errno == EAGAIN);
    }

    // There should be now 4 messages pending, consume them.
    for (int i = 0; i != 4; i++) {
        rc = xs_recv (sb, NULL, 0, 0);
        assert (rc == 0);
    }

    // Now it should be possible to send one more.
    rc = xs_send (sc, NULL, 0, 0);
    assert (rc == 0);

    //  Consume the remaining message.
    rc = xs_recv (sb, NULL, 0, 0);
    assert (rc == 0);

    rc = xs_close (sc);
    assert (rc == 0);

    rc = xs_close (sb);
    assert (rc == 0);

    rc = xs_term (ctx);
    assert (rc == 0);

    return 0;
}
コード例 #4
0
ファイル: msg_flags.cpp プロジェクト: PiotrSikora/libxs
int XS_TEST_MAIN ()
{
    fprintf (stderr, "msg_flags test running...\n");

    //  Create the infrastructure
    void *ctx = xs_init ();
    assert (ctx);
    void *sb = xs_socket (ctx, XS_XREP);
    assert (sb);
    int rc = xs_bind (sb, "inproc://a");
    assert (rc == 0);
    void *sc = xs_socket (ctx, XS_XREQ);
    assert (sc);
    rc = xs_connect (sc, "inproc://a");
    assert (rc == 0);
   
    //  Send 2-part message.
    rc = xs_send (sc, "A", 1, XS_SNDMORE);
    assert (rc == 1);
    rc = xs_send (sc, "B", 1, 0);
    assert (rc == 1);

    //  Identity comes first.
    xs_msg_t msg;
    rc = xs_msg_init (&msg);
    assert (rc == 0);
    rc = xs_recvmsg (sb, &msg, 0);
    assert (rc >= 0);
    int more;
    size_t more_size = sizeof (more);
    rc = xs_getmsgopt (&msg, XS_MORE, &more, &more_size);
    assert (rc == 0);
    assert (more == 1);

    //  Then the first part of the message body.
    rc = xs_recvmsg (sb, &msg, 0);
    assert (rc == 1);
    more_size = sizeof (more);
    rc = xs_getmsgopt (&msg, XS_MORE, &more, &more_size);
    assert (rc == 0);
    assert (more == 1);

    //  And finally, the second part of the message body.
    rc = xs_recvmsg (sb, &msg, 0);
    assert (rc == 1);
    more_size = sizeof (more);
    rc = xs_getmsgopt (&msg, XS_MORE, &more, &more_size);
    assert (rc == 0);
    assert (more == 0);

    //  Deallocate the infrastructure.
    rc = xs_close (sc);
    assert (rc == 0);
    rc = xs_close (sb);
    assert (rc == 0);
    rc = xs_term (ctx);
    assert (rc == 0);
    return 0 ;
}
コード例 #5
0
/**
 * xs_udp_connect_worker - set up a UDP socket
 * @args: RPC transport to connect
 *
 * Invoked by a work queue tasklet.
 */
static void xs_udp_connect_worker(void *args)
{
    struct rpc_xprt *xprt = (struct rpc_xprt *) args;
    struct socket *sock = xprt->sock;
    int err, status = -EIO;

    if (xprt->shutdown || xprt->addr.sin_port == 0)
        goto out;

    dprintk("RPC:      xs_udp_connect_worker for xprt %p\n", xprt);

    /* Start by resetting any existing state */
    xs_close(xprt);

    if ((err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
        dprintk("RPC:      can't create UDP transport socket (%d).\n", -err);
        goto out;
    }
    xs_reclassify_socket(sock);

    if (xs_bind(xprt, sock)) {
        sock_release(sock);
        goto out;
    }

    if (!xprt->inet) {
        struct sock *sk = sock->sk;

        write_lock_bh(&sk->sk_callback_lock);

        sk->sk_user_data = xprt;
        xprt->old_data_ready = sk->sk_data_ready;
        xprt->old_state_change = sk->sk_state_change;
        xprt->old_write_space = sk->sk_write_space;
        sk->sk_data_ready = xs_udp_data_ready;
        sk->sk_write_space = xs_udp_write_space;
        sk->sk_no_check = UDP_CSUM_NORCV;
        sk->sk_allocation = GFP_ATOMIC;

        xprt_set_connected(xprt);

        /* Reset to new socket */
        xprt->sock = sock;
        xprt->inet = sk;

        write_unlock_bh(&sk->sk_callback_lock);
    }
    xs_udp_do_set_buffer_size(xprt);
    status = 0;
out:
    xprt_wake_pending_tasks(xprt, status);
    xprt_clear_connecting(xprt);
}
コード例 #6
0
ファイル: shutdown_stress.cpp プロジェクト: PiotrSikora/libxs
int XS_TEST_MAIN ()
{
    void *ctx;
    void *s1;
    void *s2;
    int i;
    int j;
    int rc;
    int io_threads;
    void *threads [THREAD_COUNT];

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

    for (j = 0; j != 10; j++) {

        //  Check the shutdown with many parallel I/O threads.
        ctx = xs_init ();
        assert (ctx);
        io_threads = 7;
        rc = xs_setctxopt (ctx, XS_IO_THREADS, &io_threads,
            sizeof (io_threads));
        assert (rc == 0);

        s1 = xs_socket (ctx, XS_PUB);
        assert (s1);

        rc = xs_bind (s1, "tcp://127.0.0.1:5560");
        assert (rc == 0);

        for (i = 0; i != THREAD_COUNT; i++) {
            s2 = xs_socket (ctx, XS_SUB);
            assert (s2);
            threads [i] = thread_create (shutdown_stress_worker, s2);
            assert (threads [i]);
        }

        for (i = 0; i != THREAD_COUNT; i++)
            thread_join (threads [i]);

        rc = xs_close (s1);
        assert (rc == 0);

        rc = xs_term (ctx);
        assert (rc == 0);
    }

    return 0;
}
コード例 #7
0
ファイル: polltimeo.cpp プロジェクト: tailhook/libxs
int XS_TEST_MAIN ()
{
    fprintf (stderr, "polltimeo test running...\n");

    void *ctx = xs_init ();
    assert (ctx);

    //  Create a disconnected socket.
    void *sb = xs_socket (ctx, XS_PULL);
    assert (sb);
    int rc = xs_bind (sb, "inproc://timeout_test");
    assert (rc == 0);

    //  Check whether timeout is honoured.
    xs_pollitem_t pi;
    pi.socket = sb;
    pi.events = XS_POLLIN;
    void *watch = xs_stopwatch_start ();
    rc = xs_poll (&pi, 1, 500);
    assert (rc == 0);
    unsigned long elapsed = xs_stopwatch_stop (watch) / 1000;
#if !defined _WIN32 || !defined _DEBUG
    assert (elapsed > 440 && elapsed < 550);
#endif

    //  Check whether connection during the wait doesn't distort the timeout.
    void *thread = thread_create (polltimeo_worker, ctx);
    assert (thread);
    watch = xs_stopwatch_start ();
    rc = xs_poll (&pi, 1, 2000);
    assert (rc == 0);
    elapsed = xs_stopwatch_stop (watch) / 1000;
#if !defined _WIN32 || !defined _DEBUG
    assert (elapsed > 1900 && elapsed < 2100);
#endif
    thread_join (thread);

    //  Clean-up.
    rc = xs_close (sb);
    assert (rc == 0);
    rc = xs_term (ctx);
    assert (rc == 0);

    return 0 ;
}
コード例 #8
0
ファイル: local_thr.cpp プロジェクト: adeze/libxs
int main (int argc, char *argv [])
{
    const char *bind_to;
    int message_count;
    size_t message_size;
    void *ctx;
    void *s;
    int rc;
    int i;
    xs_msg_t msg;
    void *watch;
    unsigned long elapsed;
    unsigned long throughput;
    double megabits;

    if (argc != 4) {
        printf ("usage: local_thr <bind-to> <message-size> <message-count>\n");
        return 1;
    }
    bind_to = argv [1];
    message_size = atoi (argv [2]);
    message_count = atoi (argv [3]);

    ctx = xs_init ();
    if (!ctx) {
        printf ("error in xs_init: %s\n", xs_strerror (errno));
        return -1;
    }

    s = xs_socket (ctx, XS_PULL);
    if (!s) {
        printf ("error in xs_socket: %s\n", xs_strerror (errno));
        return -1;
    }

    //  Add your socket options here.
    //  For example XS_RATE, XS_RECOVERY_IVL and XS_MCAST_LOOP for PGM.

    rc = xs_bind (s, bind_to);
    if (rc == -1) {
        printf ("error in xs_bind: %s\n", xs_strerror (errno));
        return -1;
    }

    rc = xs_msg_init (&msg);
    if (rc != 0) {
        printf ("error in xs_msg_init: %s\n", xs_strerror (errno));
        return -1;
    }

    rc = xs_recvmsg (s, &msg, 0);
    if (rc < 0) {
        printf ("error in xs_recvmsg: %s\n", xs_strerror (errno));
        return -1;
    }
    if (xs_msg_size (&msg) != message_size) {
        printf ("message of incorrect size received\n");
        return -1;
    }

    watch = xs_stopwatch_start ();

    for (i = 0; i != message_count - 1; i++) {
        rc = xs_recvmsg (s, &msg, 0);
        if (rc < 0) {
            printf ("error in xs_recvmsg: %s\n", xs_strerror (errno));
            return -1;
        }
        if (xs_msg_size (&msg) != message_size) {
            printf ("message of incorrect size received\n");
            return -1;
        }
    }

    elapsed = xs_stopwatch_stop (watch);
    if (elapsed == 0)
        elapsed = 1;

    rc = xs_msg_close (&msg);
    if (rc != 0) {
        printf ("error in xs_msg_close: %s\n", xs_strerror (errno));
        return -1;
    }

    throughput = (unsigned long)
        ((double) message_count / (double) elapsed * 1000000);
    megabits = (double) (throughput * message_size * 8) / 1000000;

    printf ("message size: %d [B]\n", (int) message_size);
    printf ("message count: %d\n", (int) message_count);
    printf ("mean throughput: %d [msg/s]\n", (int) throughput);
    printf ("mean throughput: %.3f [Mb/s]\n", (double) megabits);

    rc = xs_close (s);
    if (rc != 0) {
        printf ("error in xs_close: %s\n", xs_strerror (errno));
        return -1;
    }

    rc = xs_term (ctx);
    if (rc != 0) {
        printf ("error in xs_term: %s\n", xs_strerror (errno));
        return -1;
    }

    return 0;
}
コード例 #9
0
ファイル: xszmq.cpp プロジェクト: adeze/libxs
int zmq_bind (void *s, const char *addr)
{
    int rc = xs_bind (s, addr);
    return rc < 0 ? -1 : 0;
}
コード例 #10
0
ファイル: sub_forward.cpp プロジェクト: PiotrSikora/libxs
int XS_TEST_MAIN ()
{
    fprintf (stderr, "sub_forward test running...\n");

    void *ctx = xs_init ();
    assert (ctx);

    //  First, create an intermediate device.
    void *xpub = xs_socket (ctx, XS_XPUB);
    assert (xpub);
    int rc = xs_bind (xpub, "tcp://127.0.0.1:5560");
    assert (rc == 0);
    void *xsub = xs_socket (ctx, XS_XSUB);
    assert (xsub);
    rc = xs_bind (xsub, "tcp://127.0.0.1:5561");
    assert (rc == 0);

    //  Create a publisher.
    void *pub = xs_socket (ctx, XS_PUB);
    assert (pub);
    rc = xs_connect (pub, "tcp://127.0.0.1:5561");
    assert (rc == 0);

    //  Create a subscriber.
    void *sub = xs_socket (ctx, XS_SUB);
    assert (sub);
    rc = xs_connect (sub, "tcp://127.0.0.1:5560");
    assert (rc == 0);

    //  Subscribe for all messages.
    rc = xs_setsockopt (sub, XS_SUBSCRIBE, "", 0);
    assert (rc == 0);

    //  Pass the subscription upstream through the device.
    char buff [32];
    rc = xs_recv (xpub, buff, sizeof (buff), 0);
    assert (rc >= 0);
    rc = xs_send (xsub, buff, rc, 0);
    assert (rc >= 0);

    //  Wait a bit till the subscription gets to the publisher.
    sleep (1);

    //  Send an empty message.
    rc = xs_send (pub, NULL, 0, 0);
    assert (rc == 0);

    //  Pass the message downstream through the device.
    rc = xs_recv (xsub, buff, sizeof (buff), 0);
    assert (rc >= 0);
    rc = xs_send (xpub, buff, rc, 0);
    assert (rc >= 0);

    //  Receive the message in the subscriber.
    rc = xs_recv (sub, buff, sizeof (buff), 0);
    assert (rc == 0);

    //  Clean up.
    rc = xs_close (xpub);
    assert (rc == 0);
    rc = xs_close (xsub);
    assert (rc == 0);
    rc = xs_close (pub);
    assert (rc == 0);
    rc = xs_close (sub);
    assert (rc == 0);
    rc = xs_term (ctx);
    assert (rc == 0);

    return 0 ;
}
コード例 #11
0
/**
 * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
 * @args: RPC transport to connect
 *
 * Invoked by a work queue tasklet.
 */
static void xs_tcp_connect_worker(void *args)
{
    struct rpc_xprt *xprt = (struct rpc_xprt *)args;
    struct socket *sock = xprt->sock;
    int err, status = -EIO;

    if (xprt->shutdown || xprt->addr.sin_port == 0)
        goto out;

    dprintk("RPC:      xs_tcp_connect_worker for xprt %p\n", xprt);

    if (!xprt->sock) {
        /* start from scratch */
        if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
            dprintk("RPC:      can't create TCP transport socket (%d).\n", -err);
            goto out;
        }
        xs_reclassify_socket(sock);

        if (xs_bind(xprt, sock)) {
            sock_release(sock);
            goto out;
        }
    } else
        /* "close" the socket, preserving the local port */
        xs_tcp_reuse_connection(xprt);

    if (!xprt->inet) {
        struct sock *sk = sock->sk;

        write_lock_bh(&sk->sk_callback_lock);

        sk->sk_user_data = xprt;
        xprt->old_data_ready = sk->sk_data_ready;
        xprt->old_state_change = sk->sk_state_change;
        xprt->old_write_space = sk->sk_write_space;
        sk->sk_data_ready = xs_tcp_data_ready;
        sk->sk_state_change = xs_tcp_state_change;
        sk->sk_write_space = xs_tcp_write_space;
        sk->sk_allocation = GFP_ATOMIC;

        /* socket options */
        sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
        sock_reset_flag(sk, SOCK_LINGER);
        tcp_sk(sk)->linger2 = 0;
        tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;

        xprt_clear_connected(xprt);

        /* Reset to new socket */
        xprt->sock = sock;
        xprt->inet = sk;

        write_unlock_bh(&sk->sk_callback_lock);
    }

    /* Tell the socket layer to start connecting... */
    xprt->stat.connect_count++;
    xprt->stat.connect_start = jiffies;
    status = kernel_connect(sock, (struct sockaddr *) &xprt->addr,
                            sizeof(xprt->addr), O_NONBLOCK);
    dprintk("RPC: %p  connect status %d connected %d sock state %d\n",
            xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
    if (status < 0) {
        switch (status) {
        case -EINPROGRESS:
        case -EALREADY:
            goto out_clear;
        case -ECONNREFUSED:
        case -ECONNRESET:
            /* retry with existing socket, after a delay */
            break;
        case -ENETUNREACH:
            status = -ENOTCONN;
            break;
        default:
            /* get rid of existing socket, and retry */
            xs_close(xprt);
            break;
        }
    }
out:
    xprt_wake_pending_tasks(xprt, status);
out_clear:
    xprt_clear_connecting(xprt);
}
コード例 #12
0
ファイル: inproc_lat.cpp プロジェクト: adeze/libxs
int main (int argc, char *argv [])
{
#if defined XS_HAVE_WINDOWS
    HANDLE local_thread;
#else
    pthread_t local_thread;
#endif
    void *ctx;
    void *s;
    int rc;
    int i;
    xs_msg_t msg;
    void *watch;
    unsigned long elapsed;
    double latency;

    if (argc != 3) {
        printf ("usage: inproc_lat <message-size> <roundtrip-count>\n");
        return 1;
    }

    message_size = atoi (argv [1]);
    roundtrip_count = atoi (argv [2]);

    ctx = xs_init ();
    if (!ctx) {
        printf ("error in xs_init: %s\n", xs_strerror (errno));
        return -1;
    }

    s = xs_socket (ctx, XS_REQ);
    if (!s) {
        printf ("error in xs_socket: %s\n", xs_strerror (errno));
        return -1;
    }

    rc = xs_bind (s, "inproc://lat_test");
    if (rc == -1) {
        printf ("error in xs_bind: %s\n", xs_strerror (errno));
        return -1;
    }

#if defined XS_HAVE_WINDOWS
    local_thread = (HANDLE) _beginthreadex (NULL, 0,
        worker, ctx, 0 , NULL);
    if (local_thread == 0) {
        printf ("error in _beginthreadex\n");
        return -1;
    }
#else
    rc = pthread_create (&local_thread, NULL, worker, ctx);
    if (rc != 0) {
        printf ("error in pthread_create: %s\n", xs_strerror (rc));
        return -1;
    }
#endif

    rc = xs_msg_init_size (&msg, message_size);
    if (rc != 0) {
        printf ("error in xs_msg_init_size: %s\n", xs_strerror (errno));
        return -1;
    }
    memset (xs_msg_data (&msg), 0, message_size);

    printf ("message size: %d [B]\n", (int) message_size);
    printf ("roundtrip count: %d\n", (int) roundtrip_count);

    watch = xs_stopwatch_start ();

    for (i = 0; i != roundtrip_count; i++) {
        rc = xs_sendmsg (s, &msg, 0);
        if (rc < 0) {
            printf ("error in xs_sendmsg: %s\n", xs_strerror (errno));
            return -1;
        }
        rc = xs_recvmsg (s, &msg, 0);
        if (rc < 0) {
            printf ("error in xs_recvmsg: %s\n", xs_strerror (errno));
            return -1;
        }
        if (xs_msg_size (&msg) != message_size) {
            printf ("message of incorrect size received\n");
            return -1;
        }
    }

    elapsed = xs_stopwatch_stop (watch);

    rc = xs_msg_close (&msg);
    if (rc != 0) {
        printf ("error in xs_msg_close: %s\n", xs_strerror (errno));
        return -1;
    }

    latency = (double) elapsed / (roundtrip_count * 2);

#if defined XS_HAVE_WINDOWS
    DWORD rc2 = WaitForSingleObject (local_thread, INFINITE);
    if (rc2 == WAIT_FAILED) {
        printf ("error in WaitForSingleObject\n");
        return -1;
    }
    BOOL rc3 = CloseHandle (local_thread);
    if (rc3 == 0) {
        printf ("error in CloseHandle\n");
        return -1;
    }
#else
    rc = pthread_join (local_thread, NULL);
    if (rc != 0) {
        printf ("error in pthread_join: %s\n", xs_strerror (rc));
        return -1;
    }
#endif

    printf ("average latency: %.3f [us]\n", (double) latency);

    rc = xs_close (s);
    if (rc != 0) {
        printf ("error in xs_close: %s\n", xs_strerror (errno));
        return -1;
    }

    rc = xs_term (ctx);
    if (rc != 0) {
        printf ("error in xs_term: %s\n", xs_strerror (errno));
        return -1;
    }

    return 0;
}
コード例 #13
0
ファイル: reqrep_device.cpp プロジェクト: jianjin/libxs
int XS_TEST_MAIN ()
{
    fprintf (stderr, "reqrep_device test running...\n");

    void *ctx = xs_init ();
    errno_assert (ctx);

    //  Create a req/rep device.
    void *xreq = xs_socket (ctx, XS_XREQ);
    errno_assert (xreq);
    int rc = xs_bind (xreq, "tcp://127.0.0.1:5560");
    errno_assert (rc != -1);
    void *xrep = xs_socket (ctx, XS_XREP);
    errno_assert (xrep);
    rc = xs_bind (xrep, "tcp://127.0.0.1:5561");
    errno_assert (rc != -1);

    //  Create a worker.
    void *rep = xs_socket (ctx, XS_REP);
    errno_assert (rep);
    rc = xs_connect (rep, "tcp://127.0.0.1:5560");
    errno_assert (rc != -1);

    //  Create a client.
    void *req = xs_socket (ctx, XS_REQ);
    errno_assert (req);
    rc = xs_connect (req, "tcp://127.0.0.1:5561");
    errno_assert (rc != -1);

    //  Send a request.
    rc = xs_send (req, "ABC", 3, XS_SNDMORE);
    errno_assert (rc == 3);
    rc = xs_send (req, "DEF", 3, 0);
    errno_assert (rc == 3);

    //  Pass the request through the device.
    for (int i = 0; i != 4; i++) {
        xs_msg_t msg;
        rc = xs_msg_init (&msg);
        errno_assert (rc == 0);
        rc = xs_recvmsg (xrep, &msg, 0);
        errno_assert (rc >= 0);
        int rcvmore;
        size_t sz = sizeof (rcvmore);
        rc = xs_getsockopt (xrep, XS_RCVMORE, &rcvmore, &sz);
        errno_assert (rc == 0);
        rc = xs_sendmsg (xreq, &msg, rcvmore ? XS_SNDMORE : 0);
        errno_assert (rc >= 0);
    }

    //  Receive the request.
    char buff [3];
    rc = xs_recv (rep, buff, 3, 0);
    errno_assert (rc == 3);
    assert (memcmp (buff, "ABC", 3) == 0);
    int rcvmore;
    size_t sz = sizeof (rcvmore);
    rc = xs_getsockopt (rep, XS_RCVMORE, &rcvmore, &sz);
    errno_assert (rc == 0);
    assert (rcvmore);
    rc = xs_recv (rep, buff, 3, 0);
    errno_assert (rc == 3);
    assert (memcmp (buff, "DEF", 3) == 0);
    rc = xs_getsockopt (rep, XS_RCVMORE, &rcvmore, &sz);
    errno_assert (rc == 0);
    assert (!rcvmore);

    //  Send the reply.
    rc = xs_send (rep, "GHI", 3, XS_SNDMORE);
    errno_assert (rc == 3);
    rc = xs_send (rep, "JKL", 3, 0);
    errno_assert (rc == 3);

    //  Pass the reply through the device.
    for (int i = 0; i != 4; i++) {
        xs_msg_t msg;
        rc = xs_msg_init (&msg);
        errno_assert (rc == 0);
        rc = xs_recvmsg (xreq, &msg, 0);
        errno_assert (rc >= 0);
        rc = xs_getsockopt (xreq, XS_RCVMORE, &rcvmore, &sz);
        errno_assert (rc == 0);
        rc = xs_sendmsg (xrep, &msg, rcvmore ? XS_SNDMORE : 0);
        errno_assert (rc >= 0);
    }

    //  Receive the reply.
    rc = xs_recv (req, buff, 3, 0);
    errno_assert (rc == 3);
    assert (memcmp (buff, "GHI", 3) == 0);
    rc = xs_getsockopt (req, XS_RCVMORE, &rcvmore, &sz);
    errno_assert (rc == 0);
    assert (rcvmore);
    rc = xs_recv (req, buff, 3, 0);
    errno_assert (rc == 3);
    assert (memcmp (buff, "JKL", 3) == 0);
    rc = xs_getsockopt (req, XS_RCVMORE, &rcvmore, &sz);
    errno_assert (rc == 0);
    assert (!rcvmore);

    //  Clean up.
    rc = xs_close (req);
    errno_assert (rc == 0);
    rc = xs_close (rep);
    errno_assert (rc == 0);
    rc = xs_close (xrep);
    errno_assert (rc == 0);
    rc = xs_close (xreq);
    errno_assert (rc == 0);
    rc = xs_term (ctx);
    errno_assert (rc == 0);

    return 0 ;
}
コード例 #14
0
ファイル: inproc_thr.cpp プロジェクト: carthagezz/libxs
int main (int argc, char *argv [])
{
#if defined XS_HAVE_WINDOWS
    HANDLE local_thread;
#else
    pthread_t local_thread;
#endif
    void *ctx;
    void *s;
    int rc;
    int i;
    xs_msg_t msg;
    void *watch;
    unsigned long elapsed;
    unsigned long throughput;
    double megabits;

    if (argc != 3) {
        printf ("usage: thread_thr <message-size> <message-count>\n");
        return 1;
    }

    message_size = atoi (argv [1]);
    message_count = atoi (argv [2]);

    ctx = xs_init ();
    if (!ctx) {
        printf ("error in xs_init: %s\n", xs_strerror (errno));
        return -1;
    }

    s = xs_socket (ctx, XS_PULL);
    if (!s) {
        printf ("error in xs_socket: %s\n", xs_strerror (errno));
        return -1;
    }

    rc = xs_bind (s, "inproc://thr_test");
    if (rc == -1) {
        printf ("error in xs_bind: %s\n", xs_strerror (errno));
        return -1;
    }

#if defined XS_HAVE_WINDOWS
    local_thread = (HANDLE) _beginthreadex (NULL, 0,
        worker, ctx, 0 , NULL);
    if (local_thread == 0) {
        printf ("error in _beginthreadex\n");
        return -1;
    }
#else
    rc = pthread_create (&local_thread, NULL, worker, ctx);
    if (rc != 0) {
        printf ("error in pthread_create: %s\n", xs_strerror (rc));
        return -1;
    }
#endif

    rc = xs_msg_init (&msg);
    if (rc != 0) {
        printf ("error in xs_msg_init: %s\n", xs_strerror (errno));
        return -1;
    }

    printf ("message size: %d [B]\n", (int) message_size);
    printf ("message count: %d\n", (int) message_count);

    rc = xs_recvmsg (s, &msg, 0);
    if (rc < 0) {
        printf ("error in xs_recvmsg: %s\n", xs_strerror (errno));
        return -1;
    }
    if (xs_msg_size (&msg) != message_size) {
        printf ("message of incorrect size received\n");
        return -1;
    }

    watch = xs_stopwatch_start ();

    for (i = 0; i != message_count - 1; i++) {
        rc = xs_recvmsg (s, &msg, 0);
        if (rc < 0) {
            printf ("error in xs_recvmsg: %s\n", xs_strerror (errno));
            return -1;
        }
        if (xs_msg_size (&msg) != message_size) {
            printf ("message of incorrect size received\n");
            return -1;
        }
    }

    elapsed = xs_stopwatch_stop (watch);
    if (elapsed == 0)
        elapsed = 1;

    rc = xs_msg_close (&msg);
    if (rc != 0) {
        printf ("error in xs_msg_close: %s\n", xs_strerror (errno));
        return -1;
    }

#if defined XS_HAVE_WINDOWS
    DWORD rc2 = WaitForSingleObject (local_thread, INFINITE);
    if (rc2 == WAIT_FAILED) {
        printf ("error in WaitForSingleObject\n");
        return -1;
    }
    BOOL rc3 = CloseHandle (local_thread);
    if (rc3 == 0) {
        printf ("error in CloseHandle\n");
        return -1;
    }
#else
    rc = pthread_join (local_thread, NULL);
    if (rc != 0) {
        printf ("error in pthread_join: %s\n", xs_strerror (rc));
        return -1;
    }
#endif

    rc = xs_close (s);
    if (rc != 0) {
        printf ("error in xs_close: %s\n", xs_strerror (errno));
        return -1;
    }

    rc = xs_term (ctx);
    if (rc != 0) {
        printf ("error in xs_term: %s\n", xs_strerror (errno));
        return -1;
    }

    throughput = (unsigned long)
        ((double) message_count / (double) elapsed * 1000000);
    megabits = (double) (throughput * message_size * 8) / 1000000;

    printf ("mean throughput: %d [msg/s]\n", (int) throughput);
    printf ("mean throughput: %.3f [Mb/s]\n", (double) megabits);

    return 0;
}
コード例 #15
0
ファイル: survey.cpp プロジェクト: carthagezz/libxs
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 ;
}