Exemplo n.º 1
0
/*---------------------------------------------------------------------------*/
static int on_msg_error(struct xio_session *session,
			enum xio_status error,
			enum xio_msg_direction direction,
			struct xio_msg  *msg,
			void *cb_user_context)
{
	struct test_params *test_params = (struct test_params *)cb_user_context;

	if (direction == XIO_MSG_DIRECTION_OUT) {
		printf("**** [%p] message %lu failed. reason: %s\n",
		       session, msg->sn, xio_strerror(error));
	} else {
		xio_release_response(msg);
		printf("**** [%p] message %lu failed. reason: %s\n",
		       session, msg->request->sn, xio_strerror(error));
	}

	msg_pool_put(test_params->pool, msg);

	switch (error) {
	case XIO_E_MSG_FLUSHED:
		break;
	default:
		xio_disconnect(test_params->connection);
		break;
	};

	return 0;
}
Exemplo n.º 2
0
/*---------------------------------------------------------------------------*/
static int on_session_event(struct xio_session *session,
		struct xio_session_event_data *event_data,
		void *cb_user_context)
{
	printf("session event: %s. reason: %s\n",
	       xio_session_event_str(event_data->event),
	       xio_strerror(event_data->reason));

	switch (event_data->event) {
	case XIO_SESSION_REJECT_EVENT:
	case XIO_SESSION_CONNECTION_DISCONNECTED_EVENT:
		xio_disconnect(event_data->conn);
		break;
	case XIO_SESSION_TEARDOWN_EVENT:
		xio_ev_loop_stop(loop);  /* exit */
		break;
	default:
		break;
	};

	if (pool) {
		msg_pool_free(pool);
		pool = NULL;
	}

	return 0;
}
Exemplo n.º 3
0
/*---------------------------------------------------------------------------*/
static int on_request(struct xio_session *session,
		      struct xio_msg *req,
		      int last_in_rxq,
		      void *cb_user_context)
{
	struct server_data *server_data =
		(struct server_data *)cb_user_context;
	int i = req->sn % QUEUE_DEPTH;

	/* process request */
	process_request(server_data, req);

	/* attach request to response */
	server_data->rsp[i].request = req;

	xio_send_response(&server_data->rsp[i]);
	server_data->nsent++;

	if (test_disconnect) {
		if (server_data->nsent == DISCONNECT_NR) {
			xio_disconnect(server_data->connection);
			return 0;
		}
	}
	return 0;
}
Exemplo n.º 4
0
/*---------------------------------------------------------------------------*/
static int on_send_response_complete(struct xio_session *session,
                                     struct xio_msg *msg,
                                     void *cb_prv_data)
{
    struct thread_data	*tdata = (struct thread_data *)cb_prv_data;
    struct server_data	*sdata  = tdata->sdata;

    tdata->ncomp++;

    /* can be safely freed */
    msg_pool_put(tdata->pool, msg);

    if (sdata->finite_run && tdata->ncomp == DISCONNECT_NR) {
        pthread_spin_lock(&sdata->lock);
        if (tdata->sdata->disconnected == 0) {
            int			i;

            sdata->disconnected = 1;
            pthread_spin_unlock(&sdata->lock);

            for (i = 0; i < sdata->tdata_nr; i++)
                if (sdata->tdata[i].connection)
                    xio_disconnect(sdata->tdata[i].connection);
        } else
            pthread_spin_unlock(&sdata->lock);
    }

    return 0;
}
/*---------------------------------------------------------------------------*/
int xio_on_setup_rsp_send_comp(struct xio_connection *connection,
			       struct xio_task *task)
{
	TRACE_LOG("got session setup response comp. session:%p, " \
		  "connection:%p\n",
		  connection->session, connection);

	kfree(task->omsg);

	/* recycle the task */
	xio_tasks_pool_put(task);

	/* time to set new callback */
	DEBUG_LOG("task recycled\n");

	switch (connection->session->state) {
	case XIO_SESSION_STATE_ACCEPTED:
	case XIO_SESSION_STATE_REJECTED:
	case XIO_SESSION_STATE_REDIRECTED:
		xio_disconnect(connection);
		break;
	default:
		/* try to transmit now */
		xio_connection_xmit_msgs(connection);
		break;
	}

	return 0;
}
Exemplo n.º 6
0
static void xio_module_down(void *data)
{
	struct test_params *params;
	struct xio_session *session;
	struct xio_connection *connection;

	params = (struct test_params *)data;

	if (!params->session)
		goto stop_loop_now;

	if (!params->connection)
		goto destroy_session;

	connection = params->connection;
	params->connection = NULL;
	xio_disconnect(connection);

	return;

destroy_session:
	/* in multi thread version on need to user reference count */
	session = params->session;
	params->session = NULL;
	xio_session_destroy(session);

stop_loop_now:
	/* No session -> no XIO_SESSION_TEARDOWN_EVENT */
	xio_context_stop_loop(params->ctx); /* exit */
}
Exemplo n.º 7
0
/*---------------------------------------------------------------------------*/
static int on_session_event(struct xio_session *session,
		struct xio_session_event_data *event_data,
		void *cb_user_context)
{
	struct hw_session_data *session_data = cb_user_context;

	printk("session event: %s. reason: %s\n",
	       xio_session_event_str(event_data->event),
	       xio_strerror(event_data->reason));

	switch (event_data->event) {
	case XIO_SESSION_REJECT_EVENT:
	case XIO_SESSION_CONNECTION_DISCONNECTED_EVENT:
		xio_disconnect(event_data->conn);
		break;
	case XIO_SESSION_TEARDOWN_EVENT:
		xio_session_close(session);
		/* exit */
		xio_ev_loop_stop(session_data->ctx);
		break;
	default:
		break;
	};

	return 0;
}
Exemplo n.º 8
0
/*---------------------------------------------------------------------------*/
static int on_session_event(struct xio_session *session,
		struct xio_session_event_data *event_data,
		void *cb_user_context)
{
	struct session_data *session_data = cb_user_context;
	/*printf("session event: %s. reason: %s\n",
	       xio_session_event_str(event_data->event),
	       xio_strerror(event_data->reason));
	*/
	switch (event_data->event) {
	case XIO_SESSION_REJECT_EVENT:
	case XIO_SESSION_CONNECTION_DISCONNECTED_EVENT:
		xio_disconnect(event_data->conn);
		break;
	case XIO_SESSION_TEARDOWN_EVENT:
		session_data->tdata->teared_nr++;
		//fprintf(stderr, "session #%d established:\n", sessions_counter);

		xio_session_close(session);

		if(session_data->tdata->teared_nr == session_data->tdata->num_sessions) {
			//fprintf(stderr, "All sessions( %d )are established, stopping event loop\n", sessions_counter);
			xio_ev_loop_stop(session_data->tdata->loop);
			session_data->tdata->teared_nr = 0;
		}
		break;
	default:
		break;
	};

	return 0;
}
Exemplo n.º 9
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
		       struct xio_msg *rsp,
		       int more_in_batch,
		       void *cb_user_context)
{
	struct session_data *session_data = cb_user_context;
	int i = rsp->request->sn % QUEUE_DEPTH;

	session_data->nrecv++;
	/* process the incoming message */
	process_response(session_data, rsp);

	/* acknowledge xio that response is no longer needed */
	xio_release_response(rsp);

#if  TEST_DISCONNECT
	if (session_data->nrecv == DISCONNECT_NR) {
		xio_disconnect(session_data->conn);
		return 0;
	}
	if (session_data->nsent == DISCONNECT_NR)
		return 0;
#endif

	session_data->req[i].in.header.iov_base	  = NULL;
	session_data->req[i].in.header.iov_len	  = 0;
	vmsg_sglist_set_nents(&session_data->req[i].in, 0);

	/* resend the message */
	xio_send_request(session_data->conn, &session_data->req[i]);
	session_data->nsent++;

	return 0;
}
Exemplo n.º 10
0
static void xio_module_down(void *data)
{
	struct xio_session *tmp_session;
	struct xio_connection *tmp_connection;

	if (!g_session)
		goto stop_loop_now;

	if (!g_connection)
		goto destroy_session;

	tmp_connection = g_connection;
	g_connection = NULL;
	xio_disconnect(tmp_connection);

	return;

destroy_session:
	/* in multi thread version on need to user reference count */
	tmp_session = g_session;
	g_session = NULL;
	xio_session_destroy(tmp_session);

stop_loop_now:
	/* No session -> no XIO_SESSION_TEARDOWN_EVENT */
	xio_context_stop_loop(ctx); /* exit */
}
Exemplo n.º 11
0
/*---------------------------------------------------------------------------*/
static int on_request(struct xio_session *session,
			struct xio_msg *req,
			int more_in_batch,
			void *cb_user_context)
{
	struct thread_data	*tdata = cb_user_context;
	int i = req->sn % QUEUE_DEPTH;

	/* process request */
	process_request(tdata, req);

	/* attach request to response */
	tdata->rsp[i].request = req;

	xio_send_response(&tdata->rsp[i]);
	tdata->nsent++;

#if  TEST_DISCONNECT
	if (tdata->nsent == DISCONNECT_NR) {
		struct xio_connection *connection =
			xio_get_connection(session,tdata->ctx);
		xio_disconnect(connection);
		return 0;
	}
#endif

	return 0;
}
Exemplo n.º 12
0
/*---------------------------------------------------------------------------*/
static int on_request(struct xio_session *session,
		      struct xio_msg *req,
		      int last_in_rxq,
		      void *cb_user_context)
{
	struct server_data *server_data = (struct server_data *)cb_user_context;
	struct xio_msg	   *rsp = ring_get_next_msg(server_data);

	/* process request */
	process_request(server_data, req);

	/* attach request to response */
	rsp->request = req;

	xio_send_response(rsp);
	server_data->nsent++;

	if (test_disconnect) {
		if (server_data->nsent == DISCONNECT_NR) {
			xio_disconnect(server_data->connection);
			return 0;
		}
	}
	return 0;
}
Exemplo n.º 13
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
		       struct xio_msg *msg,
		       int last_in_rxq,
		       void *cb_user_context)
{
	/* struct scatterlist	*sgl; */

	process_response(msg);

	/* message is no longer needed */
	xio_release_response(msg);

	nrecv++;

	msg_pool_put(pool, msg);

	if (test_config.finite_run) {
		if (nrecv ==  disconnect_nr) {
			xio_disconnect(g_connection);
			return 0;
		}

		if (nrecv > disconnect_nr)
			return 0;
	}

	/* reset message */
	msg->in.header.iov_base = NULL;
	msg->in.header.iov_len = 0;
	msg->in.data_tbl.nents = 0;

	/*
	sgl = msg->in.data_tbl.sgl;
	xio_tbl_set_nents(&msg->in.data_tbl, test_config.in_iov_len);
	sg_set_buf(sgl, NULL, ONE_MB);
	*/

	msg->sn = 0;

	/* recycle the message and fill new request */
	msg_build_out_sgl(&msg_params, msg,
		  test_config.hdr_len,
		  1, test_config.data_len);

	/* try to send it */
	if (xio_send_request(g_connection, msg) == -1) {
		if (xio_errno() != EAGAIN)
			pr_err("**** [%p] Error - xio_send_msg " \
					"failed %s\n",
					session,
					xio_strerror(xio_errno()));
		msg_pool_put(pool, msg);
		/* xio_assert(0); */
	}

	return 0;
}
Exemplo n.º 14
0
/*---------------------------------------------------------------------------*/
static int on_message_delivered(struct xio_session *session,
				struct xio_msg *msg,
				int last_in_rxq,
				void *cb_user_context)
{
	struct ow_test_params *ow_params =
				(struct ow_test_params *)cb_user_context;
	struct xio_msg *new_msg;

	process_tx_message(ow_params, msg);
	ow_params->ndelivered++;

	/* can be safely returned to pool */
	msg_pool_put(ow_params->pool, msg);

	if (ow_params->finite_run) {
		if (ow_params->ndelivered == ow_params->disconnect_nr) {
			xio_disconnect(ow_params->conn);
			return 0;
		}

		if (ow_params->nsent == ow_params->disconnect_nr)
			return 0;
	}

	/* peek message from the pool */
	new_msg = msg_pool_get(ow_params->pool);
	if (new_msg == NULL) {
		printf("pool is empty\n");
		return 0;
	}

	/* assign buffers to the message */
	msg_write(&ow_params->msg_params, new_msg,
		  test_config.hdr_len,
		  1, test_config.data_len);

	/*
	 * ask for receipt since we need to put the message back
	 * to pool
	 */
	 new_msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT;

	/* send it */
	if (xio_send_msg(ow_params->conn, new_msg) == -1) {
		if (xio_errno() != EAGAIN)
			printf("**** [%p] Error - xio_send_msg " \
					"failed. %s\n",
					session,
					xio_strerror(xio_errno()));
		msg_pool_put(ow_params->pool, new_msg);
		xio_assert(0);
	}
	ow_params->nsent++;

	return 0;
}
Exemplo n.º 15
0
static int on_session_established(struct xio_session *session,
		struct xio_new_session_rsp *rsp,
		void *cb_user_context)
{
	struct session_data *session_data = (struct session_data *) cb_user_context;
	//fprintf(stderr, "session established\n");
	xio_disconnect(session_data->conn);
	return 0;
}
Exemplo n.º 16
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session, struct xio_msg *rsp,
		       int more_in_batch, void *cb_user_context)
{
	struct xio_iovec_ex	*sglist;

	process_response(rsp);

	/* message is no longer needed */
	xio_release_response(rsp);

	nrecv++;
	if (test_config.finite_run) {
		if (nrecv == disconnect_nr) {
			xio_disconnect(conn);
			return 0;
		}

		if (nrecv > disconnect_nr || nsent == disconnect_nr)
			return 0;
	}

	/* reset message */
	rsp->in.header.iov_base = NULL;
	rsp->in.header.iov_len = 0;
	sglist = vmsg_sglist(&rsp->in);
	vmsg_sglist_set_nents(&rsp->in, 1);

	sglist[0].iov_base = NULL;
	sglist[0].iov_len  = ONE_MB;
	sglist[0].mr = NULL;

	rsp->sn = 0;
	rsp->more_in_batch = 0;
	do {
		/* recycle the message and fill new request */
		msg_write(&msg_params, rsp,
			  test_config.hdr_len,
			  1, test_config.data_len);

		/* try to send it */
		if (xio_send_request(conn, rsp) == -1) {
			if (xio_errno() != EAGAIN)
				printf("**** [%p] Error - xio_send_msg " \
				       "failed %s\n",
				       session,
				       xio_strerror(xio_errno()));
			msg_pool_put(pool, rsp);
			xio_assert(0);
		}
		nsent++;
	} while (0);

	return 0;
}
Exemplo n.º 17
0
/*---------------------------------------------------------------------------*/
static void signal_handler(int sig)
{
	if (sig == SIGHUP)
		reload_flag = 1;
	else
		exit_flag = 1;

	if (session_data.conn)
		xio_disconnect(session_data.conn);
	else
		xio_context_stop_loop(session_data.ctx);  /* exit */
}
Exemplo n.º 18
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
			struct xio_msg *msg,
			int last_in_rxq,
			void *cb_user_context)
{
	struct thread_data  *tdata = (struct thread_data *)cb_user_context;

	cycles_t rtt = (get_cycles()-(cycles_t)msg->user_context);

	if (tdata->do_stat) {
		if (rtt > tdata->stat.max_rtt)
			tdata->stat.max_rtt = rtt;
		if (rtt < tdata->stat.min_rtt)
			tdata->stat.min_rtt = rtt;
		tdata->stat.tot_rtt += rtt;
		tdata->stat.ccnt++;
	}

	tdata->rx_nr++;

	/* message is no longer needed */
	xio_release_response(msg);

	if (tdata->disconnect) {
		if (tdata->rx_nr == tdata->tx_nr)
			xio_disconnect(tdata->conn);
		else
			msg_pool_put(tdata->pool, msg);
		return 0;
	}

	/* reset message */
	msg->in.header.iov_len = 0;
	vmsg_sglist_set_nents(&msg->in, 0);

	msg->user_context = (void *)get_cycles();
	if (xio_send_request(tdata->conn, msg) == -1) {
		if (xio_errno() != EAGAIN)
			printf("**** [%p] Error - xio_send_request " \
					"failed %s\n",
					session,
					xio_strerror(xio_errno()));
		msg_pool_put(tdata->pool, msg);
		return 0;
	}
	if (tdata->do_stat)
		tdata->stat.scnt++;

	tdata->tx_nr++;

	return 0;
}
Exemplo n.º 19
0
/*---------------------------------------------------------------------------*/
static int on_message_delivered(struct xio_session *session,
                                struct xio_msg *msg,
                                int more_in_batch,
                                void *cb_user_context)
{
    struct xio_msg *new_msg;
    struct ow_test_params *ow_params = cb_user_context;

    ow_params->ndelivered++;

    /* can be safely freed */
    msg_pool_put(ow_params->pool, msg);

#if  TEST_DISCONNECT
    if (ow_params->ndelivered == DISCONNECT_NR) {
        xio_disconnect(ow_params->connection);
        return 0;
    }

    if (ow_params->nsent == DISCONNECT_NR)
        return 0;
#endif

    /* peek new message from the pool */
    new_msg	= msg_pool_get(ow_params->pool);

    new_msg->more_in_batch	= 0;

    /* fill response */
    msg_write(&ow_params->msg_params, new_msg,
              NULL, test_config.hdr_len,
              NULL, test_config.data_len);

    new_msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT;
    if (xio_send_msg(ow_params->connection, new_msg) == -1) {
        printf("**** [%p] Error - xio_send_msg failed. %s\n",
               session, xio_strerror(xio_errno()));
        msg_pool_put(ow_params->pool, new_msg);
    }
    ow_params->nsent++;


    return 0;
}
Exemplo n.º 20
0
/*---------------------------------------------------------------------------*/
static int on_send_response_complete(struct xio_session *session,
			struct xio_msg *msg,
			void *cb_user_context)
{
	struct test_params *test_params = cb_user_context;

	test_params->ncomp++;

	/* can be safely freed */
	msg_pool_put(test_params->pool, msg);

#if  TEST_DISCONNECT
	if (test_params->ncomp == DISCONNECT_NR) {
		xio_disconnect(test_params->connection);
		return 0;
	}
#endif
	return 0;
}
Exemplo n.º 21
0
/*---------------------------------------------------------------------------*/
static int on_request(struct xio_session *session,
		      struct xio_msg *req,
		      int last_in_rxq,
		      void *cb_user_context)
{
	struct test_params *test_params = cb_user_context;

	test_params->nrecv++;

	/* process request */
	process_request(req);

	xio_release_msg(req);
	if (test_params->finite_run &&
	    test_params->nrecv == test_params->disconnect_nr) {
		xio_disconnect(test_params->connection);
		return 0;
	}

	return 0;
}
Exemplo n.º 22
0
/*---------------------------------------------------------------------------*/
static int on_msg_error(struct xio_session *session,
			enum xio_status error,
			enum xio_msg_direction direction,
			struct xio_msg  *msg,
			void *cb_user_context)
{
	pr_info("**** [%p] message [%llu] failed. reason: %s\n",
		session, msg->sn, xio_strerror(error));

	msg_pool_put(pool, msg);

	switch (error) {
	case XIO_E_MSG_FLUSHED:
		break;
	default:
		xio_disconnect(g_connection);
		break;
	};

	return 0;
}
Exemplo n.º 23
0
/*---------------------------------------------------------------------------*/
static int on_session_event(struct xio_session *session,
		struct xio_session_event_data *event_data,
		void *cb_user_context)
{
	struct xio_connection_params cparams;
	struct test_params *test_params = cb_user_context;

	printf("session event: %s. session:%p, connection:%p, reason: %s\n",
	       xio_session_event_str(event_data->event),
	       session, event_data->conn,
	       xio_strerror(event_data->reason));

	switch (event_data->event) {
	case XIO_SESSION_NEW_CONNECTION_EVENT:
		/* assign connection private data */
		cparams.user_context = cb_user_context;
		xio_set_connection_params(event_data->conn, &cparams);
		break;
	case XIO_SESSION_REJECT_EVENT:
		xio_disconnect(event_data->conn);
		break;
	case XIO_SESSION_CONNECTION_TEARDOWN_EVENT:
		printf("last sent:%"PRIu64", last comp:%"PRIu64", " \
		       "delta:%"PRIu64"\n",
		       test_params->nsent,  test_params->ncomp,
		       test_params->nsent-test_params->ncomp);
		xio_connection_destroy(event_data->conn);
		break;
	case XIO_SESSION_TEARDOWN_EVENT:
		xio_session_destroy(session);
		xio_context_stop_loop(test_params->ctx, 0);
		break;
	default:
		break;
	};

	return 0;
}
Exemplo n.º 24
0
/*---------------------------------------------------------------------------*/
static int on_msg_send_complete(struct xio_session *session,
				struct xio_msg *msg,
				void *cb_user_context)
{
	struct test_params *test_params = cb_user_context;
	process_message(test_params, msg);

	test_params->ncomp++;

	/* can be safely freed */
	msg_pool_put(test_params->pool, msg);

	if (test_params->finite_run) {
		if ((test_params->ncomp+test_params->ndelivered) >
		       test_params->disconnect_nr)
			return 0;
		if ((test_params->ncomp + test_params->ndelivered) ==
		     test_params->disconnect_nr) {
			xio_disconnect(test_params->connection);
			return 0;
		}
	}

	if (test_params->closed)
		return 0;

	/* peek message from the pool */
	msg = msg_pool_get(test_params->pool);
	if (msg == NULL) {
		printf("pool is empty\n");
		return 0;
	}

	/* reset message */
	msg->in.header.iov_base = NULL;
	msg->in.header.iov_len	= 0;
	msg->in.data_iov.nents	= 0;
	msg->more_in_batch	= 0;

	/* assign buffers to the message */
	msg_write(&test_params->msg_params, msg,
		  test_config.hdr_len,
		  1, test_config.data_len);

	/* try to send it */
	if (test_params->ask_for_receipt)
		msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT;
	else
		msg->flags = 0;



	if (xio_send_msg(test_params->connection, msg) == -1) {
		if (xio_errno() != EAGAIN)
			printf("**** [%p] Error - xio_send_request " \
					"failed %s\n",
					session,
					xio_strerror(xio_errno()));
		msg_pool_put(test_params->pool, msg);
		xio_assert(0);
	}
	test_params->nsent++;

	return 0;
}
Exemplo n.º 25
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
		       struct xio_msg *msg,
		       int last_in_rxq,
		       void *cb_user_context)
{
	struct test_params *test_params = (struct test_params *)cb_user_context;
	struct xio_iovec_ex	*sglist;
	static int		chain_messages = CHAIN_MESSAGES;
	size_t			j;

	test_params->nrecv++;

	process_response(test_params, msg);

	/* message is no longer needed */
	xio_release_response(msg);

	msg_pool_put(test_params->pool, msg);

	if (test_params->finite_run) {
		if (test_params->nrecv ==  test_params->disconnect_nr) {
			xio_disconnect(test_params->connection);
			return 0;
		}

		if (test_params->nsent == test_params->disconnect_nr)
			return 0;
	}

	/* peek message from the pool */
	msg = msg_pool_get(test_params->pool);
	if (msg == NULL) {
		printf("pool is empty\n");
		return 0;
	}
	msg->in.header.iov_base = NULL;
	msg->in.header.iov_len = 0;

	sglist = vmsg_sglist(&msg->in);
	vmsg_sglist_set_nents(&msg->in, test_config.in_iov_len);

	/* tell accelio to use 1MB buffer from its internal pool */
	for (j = 0; j < test_config.in_iov_len; j++) {
		sglist[j].iov_base = NULL;
		sglist[j].iov_len  = ONE_MB;
		sglist[j].mr = NULL;
	}

	msg->sn = 0;

	/* assign buffers to the message */
	msg_build_out_sgl(&test_params->msg_params, msg,
		  test_config.hdr_len,
		  test_config.out_iov_len, test_config.data_len);



	if (chain_messages) {
		msg->next = NULL;
		if (test_params->chain.head  == NULL) {
			test_params->chain.head = msg;
			test_params->chain.tail = test_params->chain.head;
		} else {
			test_params->chain.tail->next = msg;
			test_params->chain.tail = test_params->chain.tail->next;
		}
		if (++test_params->chain.sz == MAX_OUTSTANDING_REQS) {
			if (xio_send_request(test_params->connection,
					     test_params->chain.head) == -1) {
				if (xio_errno() != EAGAIN)
					printf("**** [%p] Error - xio_send_request " \
							"failed %s\n",
							session,
							xio_strerror(xio_errno()));
				msg_pool_put(test_params->pool, msg);
				xio_assert(xio_errno() == EAGAIN);
			}
			test_params->nsent += test_params->chain.sz;
			test_params->chain.head = NULL;
			test_params->chain.sz = 0;
		}
	} else {
		/* try to send it */
		/*msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT; */
		/*msg->flags = XIO_MSG_FLAG_PEER_READ_REQ;*/
		if (xio_send_request(test_params->connection, msg) == -1) {
			if (xio_errno() != EAGAIN)
				printf("**** [%p] Error - xio_send_request " \
						"failed %s\n",
						session,
						xio_strerror(xio_errno()));
			msg_pool_put(test_params->pool, msg);
			xio_assert(xio_errno() == EAGAIN);
		}
		test_params->nsent++;
	}

	return 0;
}