int recv_all(psdapl_con_info_t *ci, char *buf) { void *rbuf; int len; len = psdapl_recvlook_block(ci, &rbuf); if (len == 0) { /* EOF */ return 0; } unsigned msgsize = *(unsigned *)rbuf; unsigned count = msgsize; while (1) { memcpy(buf, rbuf, len); psdapl_recvdone(ci); count -= len; if (!count) break; buf += len; len = psdapl_recvlook_block(ci, &rbuf); if (len == 0) { /* EOF */ return 0; } } return msgsize; }
/* returnvalue like read() , except on error errno is negative return */ int psdapl_recvlook(psdapl_con_info_t *ci, void **buf) { // assert(con_info->n_recv_toks == 0) as long as we only poll! while (1) { psdapl_msg_t *msg = ((psdapl_msg_t *)ci->recv_bufs.lmr_mem) + ci->recv_pos; unsigned int magic = msg->tail.magic; if (!magic) { // Nothing received psdapl_flush_evd(ci); // Maybe we have to send tokens before we can receive more: _psdapl_send_tokens(ci); return (ci->con_broken) ? -EPIPE : -EAGAIN; } msg->tail.magic = PSDAPL_MAGIC_UNUSED; /* Fresh tokens ? */ ci->n_send_toks += msg->tail.token; ci->n_recv_toks++; unsigned len = msg->tail.payload; unsigned psdapllen = PSDAPL_LEN(len); *buf = ci->recv_bufs.lmr_mem + PSDAPL_DATA_OFFSET(ci->recv_pos, psdapllen); if (len) { // receive data return len; } /* skip 0 payload packages (probably fresh tokens) */ psdapl_recvdone(ci); } }
static void psdapl_get_fresh_tokens(psdapl_con_info_t *ci) { psdapl_msg_t *msg = ((psdapl_msg_t *)ci->recv_bufs.lmr_mem) + ci->recv_pos; unsigned int magic = msg->tail.magic; if ((magic == PSDAPL_MAGIC_IO) && (msg->tail.payload == 0)) { // Fresh tokens msg->tail.magic = PSDAPL_MAGIC_UNUSED; ci->n_send_toks += msg->tail.token; ci->n_recv_toks++; psdapl_recvdone(ci); } }