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