예제 #1
0
파일: pselan.c 프로젝트: JonBau/pscom
/* returnvalue like read() , except on error errno is negative return */
int pselan_recvlook(pselan_con_info_t *ci, void **buf)
{
	// assert(con_info->n_recv_toks == 0) as long as we only poll!
	while (1) {
		pselan_msg_t *msg = ci->recv_bufs + ci->recv_pos;

		unsigned int magic = msg->tail.magic;
		if (!magic) { // Nothing received
			pselan_flush_event(ci);

			return (ci->con_broken) ? -EPIPE : -EAGAIN;
		}

		msg->tail.magic = PSELAN_MAGIC_UNUSED;

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

		unsigned len = msg->tail.payload;
		unsigned pselanlen = PSELAN_LEN(len);

		*buf = ci->recv_bufs[ci->recv_pos].data - pselanlen;
		if (len || (magic == PSELAN_MAGIC_EOF)) {
			// receive data or EOF
			return len;
		}

		/* skip 0 payload packages (probably fresh tokens) */
		pselan_recvdone(ci);
	}
}
예제 #2
0
파일: pselan.c 프로젝트: JonBau/pscom
static
void pselan_get_fresh_tokens(pselan_con_info_t *ci)
{
	pselan_msg_t *msg = ci->recv_bufs + ci->recv_pos;
	unsigned int magic = msg->tail.magic;

	if ((magic == PSELAN_MAGIC_IO) &&
	    (msg->tail.payload == 0)) {
		// Fresh tokens
		msg->tail.magic = PSELAN_MAGIC_UNUSED;
		ci->n_send_toks += msg->tail.token;
		ci->n_recv_toks++;

		pselan_recvdone(ci);
	}
}
예제 #3
0
static
int _pscom_elan_do_read(pscom_con_t *con, pselan_con_info_t *ci)
{
	void *buf;
	int size;

	size = pselan_recvlook(ci, &buf);

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

		pselan_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;
	}
}