diff options
-rw-r--r-- | mcastseed/src/dgrambuf.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/mcastseed/src/dgrambuf.c b/mcastseed/src/dgrambuf.c index 4296f89..061ae30 100644 --- a/mcastseed/src/dgrambuf.c +++ b/mcastseed/src/dgrambuf.c @@ -1,6 +1,6 @@ /* * dgrambuf.c - C datagrams buffer. - * + * * Copyright 2016 by Ludovic Pouzenc <ludovic@pouzenc.fr> */ #define _GNU_SOURCE /* See feature_test_macros(7) */ @@ -94,8 +94,9 @@ size_t dgrambuf_get_used_count(const dgrambuf_t dbuf) { ssize_t dgrambuf_recvmmsg(dgrambuf_t dbuf, int sockfd, int timeout, int *info) { uint8_t *dgram_base; ssize_t recv_byte; - size_t i, vlen, dgram_index, recv_msg_count, free_count, free_iovecs_count; + size_t i, dgram_index, recv_msg_count, free_count; int res; + bool bres; unsigned int seq, dgram_len; struct sigaction sa_old; struct indexed_uint *active_slot; @@ -110,7 +111,8 @@ ssize_t dgrambuf_recvmmsg(dgrambuf_t dbuf, int sockfd, int timeout, int *info) { } /* Buffer is full, can't receive */ - if ( dgrambuf_get_free_count(dbuf) == 0 ) { + free_count = dgrambuf_get_free_count(dbuf); + if ( free_count == 0 ) { dbuf->stats.dgrambuf_read_on_full++; *info |= DGRAMBUF_RECV_OVERWRITE; /*FIXME : this locks everything if buf full + next seq missing*/ @@ -118,15 +120,10 @@ ssize_t dgrambuf_recvmmsg(dgrambuf_t dbuf, int sockfd, int timeout, int *info) { } /* Initialize recvmmsg() syscall arguments and keep track of active slots */ - free_count = dgrambuf_get_free_count(dbuf); - free_iovecs_count = gl_list_size(dbuf->dgram_empty_slots); - - /* XXX condition is strange */ - for (i=0; i < dbuf->iovec_slots && i < free_count && i < free_iovecs_count; i++) { + for (i=0; i < dbuf->iovec_slots && i < free_count; i++) { /* Pop a free slot, ignoring const modifier from gl_list_get_at() */ dbuf->dgram_read_active_slots[i] = (struct indexed_uint *) gl_list_get_at(dbuf->dgram_empty_slots, 0); gl_list_remove_at(dbuf->dgram_empty_slots, 0); - dbuf->dgram_read_active_slots_count++; dgram_index = dbuf->dgram_read_active_slots[i]->index; dbuf->iov_recv[i].iov_base = dbuf->buf + dgram_index * dbuf->dgram_max_size; @@ -136,14 +133,14 @@ ssize_t dgrambuf_recvmmsg(dgrambuf_t dbuf, int sockfd, int timeout, int *info) { dbuf->msgs[i].msg_hdr.msg_iov = dbuf->iov_recv + i; dbuf->msgs[i].msg_hdr.msg_iovlen = 1; } - vlen = i; + dbuf->dgram_read_active_slots_count = i; /* Do the syscall with alarm() to circumvent bad behavior in recvmmsg(2) timeout */ if (timeout) { sigaction(SIGALRM, &(dbuf->sa_sigalrm), &sa_old); alarm(timeout); } - res = recvmmsg(sockfd, dbuf->msgs, vlen, MSG_WAITFORONE, NULL); + res = recvmmsg(sockfd, dbuf->msgs, dbuf->dgram_read_active_slots_count, MSG_WAITFORONE, NULL); if (timeout) { alarm(0); sigaction(SIGALRM, &sa_old, NULL); @@ -164,7 +161,7 @@ ssize_t dgrambuf_recvmmsg(dgrambuf_t dbuf, int sockfd, int timeout, int *info) { if (recv_msg_count > 0) { dbuf->stats.recv_dgrams += recv_msg_count; - if ( recv_msg_count == vlen ) { + if ( recv_msg_count == dbuf->dgram_read_active_slots_count ) { *info |= DGRAMBUF_RECV_IOVEC_FULL; } } @@ -190,10 +187,12 @@ ssize_t dgrambuf_recvmmsg(dgrambuf_t dbuf, int sockfd, int timeout, int *info) { *info |= DGRAMBUF_RECV_FUTURE_DGRAM; } else { /*fprintf(stderr, "dgrambuf_recvmmsg(): #%zu valid (%u)\n", i, seq);*/ - *info |= DGRAMBUF_RECV_VALID_DGRAM; active_slot->value = seq; - gl_sortedlist_nx_add(dbuf->dgram_used_slots, _compare_indexed_uint, active_slot); + bres = gl_sortedlist_nx_add(dbuf->dgram_used_slots, _compare_indexed_uint, active_slot); + if ( !bres ) /*TODO: better oom handling */ + return -4; dbuf->dgram_len[active_slot->index] = dgram_len; + *info |= DGRAMBUF_RECV_VALID_DGRAM; continue; } break; @@ -209,13 +208,17 @@ ssize_t dgrambuf_recvmmsg(dgrambuf_t dbuf, int sockfd, int timeout, int *info) { break; } /* In all invalid dgram cases, put back active_slot in dgram_free_slots */ - gl_sortedlist_nx_add(dbuf->dgram_empty_slots, _compare_indexed_uint, active_slot); + bres = gl_sortedlist_nx_add(dbuf->dgram_empty_slots, _compare_indexed_uint, active_slot); + if ( !bres ) /*TODO: better oom handling */ + return -4; } /* Push remaining active slots in dgram_empty_slots */ for (/*next i*/; i < dbuf->dgram_read_active_slots_count; i++) { active_slot = dbuf->dgram_read_active_slots[i]; - gl_sortedlist_nx_add(dbuf->dgram_empty_slots, _compare_indexed_uint, active_slot); + bres = gl_sortedlist_nx_add(dbuf->dgram_empty_slots, _compare_indexed_uint, active_slot); + if ( !bres ) /*TODO: better oom handling */ + return -4; } dbuf->dgram_read_active_slots_count = 0; @@ -257,6 +260,7 @@ ssize_t dgrambuf_write(dgrambuf_t dbuf, int fd, int *info) { ssize_t nwrite, total, remain, len; struct iovec *iov; struct indexed_uint *active_slot; + bool bres; /* FIXME Info ptr is mandatory */ *info = 0; @@ -372,7 +376,7 @@ ssize_t dgrambuf_write(dgrambuf_t dbuf, int fd, int *info) { dbuf->partial_write_remaining_iovcnt = vlen - i; dbuf->partial_write_iov = dbuf->iov_write + i; - dbuf->iov_write[i].iov_base = + dbuf->iov_write[i].iov_base = (uint8_t *) dbuf->iov_write[i].iov_base + remain; dbuf->iov_write[i].iov_len -= remain; break; @@ -389,7 +393,9 @@ ssize_t dgrambuf_write(dgrambuf_t dbuf, int fd, int *info) { for (i=0; i<dbuf->dgram_write_active_slots_count; i++) { active_slot = (struct indexed_uint *) dbuf->dgram_write_active_slots[i]; active_slot->value = 0; - gl_sortedlist_nx_add(dbuf->dgram_empty_slots, _compare_indexed_uint, active_slot); + bres = gl_sortedlist_nx_add(dbuf->dgram_empty_slots, _compare_indexed_uint, active_slot); + if ( !bres ) /*TODO: better oom handling */ + return -4; } dbuf->dgram_write_active_slots_count = 0; /* Wipe outdated partial_* values for clarity in debug mode (only _bytes is use on branching) */ @@ -405,7 +411,7 @@ dgrambuf_t dgrambuf_new(size_t dgram_slots, size_t dgram_max_size, size_t dgram_ const void **dgram_slot_seq_ptrs = NULL; dgrambuf_t dbuf; size_t i; - + dbuf = calloc(1, sizeof(struct dgrambuf_t)); if (!dbuf) goto fail0; |