Ejemplo n.º 1
0
Archivo: unit.c Proyecto: satrac/knc
int
knc_loop(struct knc_ctx *ctx)
{
	fd_set	 rd, wr;
	int	 fd;
	int	 i;
	int	 ret;
	int	 valrecv = 0;
	int	 valsend = 0;
	char	*buf;

	fd = knc_get_net_fd(ctx);

	/* XXXrcd: Set non-blocking? */
	ret = fcntl(fd, F_SETFL, O_NONBLOCK);
	if (ret == -1)
		fprintf(stderr, "%d: set nonblocking, %s\n",
		    getpid(), strerror(errno));

	for (;;) {
		fprintf(stderr, "%d: loop start, recv'd = %d sent = %d.\n",
		    getpid(), valrecv, valsend);

		if (knc_error(ctx))
			break;

		if (knc_get_net_fd(ctx) == -1)
			break;

		/*
		 * The data that we are sending and receiving is a simple
		 * steam of incrementing single byte integers modulo 11.
		 * Both sides send the same data, so it can be validated.
		 */

		if (knc_avail_buf(ctx, KNC_DIR_SEND) < UNIT_BUFSIZ) {
			ret = knc_get_ibuf(ctx, KNC_DIR_SEND,
			    (void **)&buf, 8192);
			if (ret == -1)
				fprintf(stderr, "%d: ret == -1 for sending\n",
				    getpid());

			for (i=0; i < ret; i++)
				buf[i] = valsend++ % 11;

			if (ret > 0)
				knc_fill_buf(ctx, KNC_DIR_SEND, ret);
		}

		if (knc_avail_buf(ctx, KNC_DIR_RECV) > 0) {

			ret = knc_get_obuf(ctx, KNC_DIR_RECV,
			    (void **)&buf, 8192);
			if (ret < 0)
				fprintf(stderr, "%d: ret == %d for receiving\n",
				    getpid(), ret);

			for (i=0; i < ret; i++) {
				if (buf[i] != valrecv++ % 11) {
					fprintf(stderr, "Malformed input\n");
					return -1;
				}
			}

			if (ret > 0)
				knc_drain_buf(ctx, KNC_DIR_RECV, ret);
		}

		FD_ZERO(&rd);
		FD_ZERO(&wr);

		if (knc_avail_buf(ctx, KNC_DIR_RECV) < UNIT_BUFSIZ)
			FD_SET(fd, &rd);

		if (knc_avail_buf(ctx, KNC_DIR_SEND) > 0)
			FD_SET(fd, &wr);

		ret = select(fd+1, &rd, &wr, NULL, NULL);
		if (ret < 0) {
			fprintf(stderr, "select: %s\n", strerror(errno));
			break;
		}

		if (FD_ISSET(fd, &rd))
			knc_fill(ctx, KNC_DIR_RECV);

		if (FD_ISSET(fd, &wr))
			knc_flush(ctx, KNC_DIR_SEND);

		knc_garbage_collect(ctx);
	}

	ret = 0;
	if (knc_error(ctx)) {
		fprintf(stderr, "KNC UNIT TEST ERROR: %s\n", knc_errstr(ctx));
		ret = 1;
	}

	knc_ctx_close(ctx);
	close(fd);
	return ret;
}
Ejemplo n.º 2
0
int
knc_loop(knc_ctx ctx, int server)
{
	int	 i;
	int	 loopcount = 0;
	int	 ret;
	int	 do_recv = 1;
	int	 do_send = 1;
	int	 valrecv = 0;
	int	 valsend = 0;
	char	*buf;

	knc_set_opt(ctx, KNC_SOCK_NONBLOCK, 1);

	for (;;) {
		knc_callback	cbs[2];
		struct pollfd	fds[4];
		nfds_t		nfds;

		fprintf(stderr, "%s: loop start (% 6d), "
		    "R=% 9d %s S=% 9d %s ToSend=%9zu\n", server?"S":"C",
		    ++loopcount, valrecv, do_recv?"    ":"done", valsend,
		    do_send?"    ":"done", knc_pending(ctx, KNC_DIR_SEND));

		if (knc_error(ctx))
			break;

		if (knc_io_complete(ctx))
			break;

		/*
		 * The data that we are sending and receiving is a simple
		 * steam of incrementing single byte integers modulo 11.
		 * Both sides send the same data, so it can be validated.
		 */

		if (do_send && knc_pending(ctx, KNC_DIR_SEND) < UNIT_BUFSIZ) {
			ret = knc_get_ibuf(ctx, KNC_DIR_SEND,
			    (void **)&buf, 8192);
			if (ret == -1)
				fprintf(stderr, "%d: ret == -1 for sending\n",
				    getpid());

			for (i=0; i < ret; i++)
				buf[i] = valsend++ % 11;

			if (ret > 0)
				knc_fill_buf(ctx, KNC_DIR_SEND, ret);
		}

		while (knc_pending(ctx, KNC_DIR_RECV) > 0) {
			ret = knc_get_obuf(ctx, KNC_DIR_RECV,
			    (void **)&buf, 8192);
			if (ret <= 0)
				break;

			for (i=0; i < ret; i++) {
				if (buf[i] != valrecv++ % 11) {
					fprintf(stderr, "Malformed input\n");
					return -1;
				}
			}

			knc_drain_buf(ctx, KNC_DIR_RECV, ret);
		}

		if (valrecv >= TEST_SIZE)
			do_recv = 0;

		if (do_send && valsend >= TEST_SIZE) {
			knc_put_eof(ctx, KNC_DIR_SEND);
			do_send = 0;
		}


		nfds = knc_get_pollfds(ctx, fds, cbs, 4);

		ret = poll(fds, nfds, 0);
		if (ret < 0) {
			fprintf(stderr, "poll: %s\n", strerror(errno));
			break;
		}

		knc_service_pollfds(ctx, fds, cbs, nfds);
	}

	fprintf(stderr, "%s: loop done  (% 6d), "
	    "R=% 9d %s S=% 9d %s ToSend=%9zu\n", server?"S":"C",
	    ++loopcount, valrecv, do_recv?"    ":"done", valsend,
	    do_send?"    ":"done", knc_pending(ctx, KNC_DIR_SEND));

	ret = 0;
	if (knc_error(ctx)) {
		fprintf(stderr, "%s: KNC UNIT TEST ERROR: %s\n",
		    server?"S":"C", knc_errstr(ctx));
		ret = 1;
	}

	knc_close(ctx);
	knc_ctx_close(ctx);
	return ret;
}