예제 #1
0
static
int _pscom_extoll_rma2_do_read(pscom_con_t *con, psex_con_info_t *ci)
{
	void *buf;
	int size;

	size = psex_recvlook(ci, &buf);

	if (size >= 0) {
		pscom_read_done(con, buf, size);

		psex_recvdone(ci);
		return 1;
	} else if ((size == -EINTR) || (size == -EAGAIN)) {
		// Nothing received
		return 0;
	} else {
		// Error
		errno = -size;
		pscom_con_error(con, PSCOM_OP_READ, PSCOM_ERR_STDERROR);
		return 1;
	}
}
예제 #2
0
파일: psextoll.c 프로젝트: JonBau/pscom
/* returnvalue like read() , except on error errno is negative return */
int psex_recvlook(psex_con_info_t *con_info, void **buf)
{
#if 1 // Simpler loop because:
	// assert(con_info->n_recv_toks == 0) as long as we only poll!
	while (1) {
		psex_msg_t *msg =
			((psex_msg_t *)con_info->recv.bufs.ptr) + con_info->recv.pos;

		unsigned int magic = msg->tail.magic;

		if (!magic) { // Nothing received
			*buf = NULL;
			// Maybe we have to send tokens before we can receive more:
			_psex_send_tokens(con_info);
			// psex_progress(con_info); Called outside the loop over all connections.
			return (con_info->con_broken) ? -EPIPE : -EAGAIN;
		}

		msg->tail.magic = PSEX_MAGIC_UNUSED;

		/* Fresh tokens ? */
		con_info->n_send_toks += msg->tail.token;
		con_info->n_recv_toks++;

		unsigned int len = msg->tail.payload;

		*buf = PSEX_DATA((char*)msg, PSEX_LEN(len));
		if (len || (magic == PSEX_MAGIC_EOF)) {
			// receive data or EOF
			return len;
		}

		/* skip 0 payload packages (probably fresh tokens) */
		psex_recvdone(con_info);
	}
#else
	unsigned int magic;
	/* Check for new packages */
	{
		psex_con_info_t *con = con_info;
		psex_msg_t *msg = ((psex_msg_t *)con->recv_bufs.ptr) +
			((con->recv_pos + con->n_recv_toks) % SIZE_SR_QUEUE);
		magic = msg->tail.magic;

		if (magic) {
//			printf("receive magic %08x\n", msg->tail.magic);
			msg->tail.magic = PSEX_MAGIC_UNUSED;

			/* Fresh tokens ? */
			con->n_send_toks += msg->tail.token;
			con->n_recv_toks++;
		}
	}

	while (con_info->n_recv_toks > 0) {
		psex_msg_t *msg = ((psex_msg_t *)con_info->recv_bufs.ptr) + con_info->recv_pos;
		int len = msg->tail.payload;

		*buf = PSEX_DATA(msg, PSEX_LEN(len));
		if (len || (magic == PSEX_MAGIC_EOF)) {
			// ToDo: This could be the wrong magic!!!
			return len;
		}
		/* skip 0 payload packages */
		psex_recvdone(con_info);
	}

	if (con_info->con_broken) {
		return -EPIPE;
	} else {
		// Maybe we have to send tokens before we ca receive more:
		_psex_send_tokens(con_info);
		return -EAGAIN;
	}
#endif
}