/* 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); } }
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); } }
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; } }