From a848893d85cd027d831ba0ecae9dacef0a5f0605 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 30 Aug 2008 17:33:07 -0700 Subject: ringbuf: create a new struct rbvec instead of reusing struct iovec Using struct iovec means having to cast iov_base everywhere we want to do pointer arithmetic. Instead, just use rbvec which can be safely casted to iovec whenever we use the readv/writev functions. --- src/inputStream_http.c | 2 +- src/outputBuffer.c | 24 ++++++++++++------------ src/outputBuffer_ob_send.h | 6 +++--- src/outputBuffer_xfade.h | 8 ++++---- src/ringbuf.c | 36 ++++++++++++++++++------------------ src/ringbuf.h | 18 ++++++++++++------ 6 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/inputStream_http.c b/src/inputStream_http.c index a6c715459..cc31ed435 100644 --- a/src/inputStream_http.c +++ b/src/inputStream_http.c @@ -461,7 +461,7 @@ static ssize_t buffer_data(InputStream *is) assert(pthread_equal(data->io_thread, pthread_self())); assert_state2(CONN_STATE_BUFFER, CONN_STATE_PREBUFFER); - if (!ringbuf_get_write_vector(data->rb, vec)) { + if (!ringbuf_get_write_vector(data->rb, (struct rbvec *)vec)) { data->state = CONN_STATE_BUFFER_FULL; return 0; } diff --git a/src/outputBuffer.c b/src/outputBuffer.c index a856c9a8c..27bb18b44 100644 --- a/src/outputBuffer.c +++ b/src/outputBuffer.c @@ -152,7 +152,7 @@ static enum action_status ob_finalize_action(void) /* marks all buffered chunks with sequence number matching `seq' as invalid */ static enum action_status ob_do_drop(void) { - struct iovec vec[2]; + struct rbvec vec[2]; long i; mpd_uint8 seq_drop; @@ -190,7 +190,7 @@ static enum action_status ob_do_pause(void) static void reader_reset_buffer(void) { - struct iovec vec[2]; + struct rbvec vec[2]; size_t nr; long i; @@ -330,15 +330,15 @@ static enum action_status ob_take_action(void) * like an infinite, rotating buffer. The first available chunk * is always indexed as `0', the second one as `1', and so on... */ -static struct ob_chunk *get_chunk(struct iovec vec[2], size_t i) +static struct ob_chunk *get_chunk(struct rbvec vec[2], size_t i) { - if (vec[0].iov_len > i) - return &ob.chunks[vec[0].iov_base + i - ob.index->buf]; - if (i && vec[1].iov_base) { - assert(vec[0].iov_len > 0); - i -= vec[0].iov_len; - if (vec[1].iov_len > i) - return &ob.chunks[vec[1].iov_base + i - ob.index->buf]; + if (vec[0].len > i) + return &ob.chunks[vec[0].base + i - ob.index->buf]; + if (i && vec[1].base) { + assert(vec[0].len > 0); + i -= vec[0].len; + if (vec[1].len > i) + return &ob.chunks[vec[1].base + i - ob.index->buf]; } return NULL; } @@ -426,7 +426,7 @@ static void send_next_tag(void) static void play_next_chunk(void) { - struct iovec vec[2]; + struct rbvec vec[2]; struct ob_chunk *a; size_t nr; static float last_time; @@ -551,7 +551,7 @@ void ob_seek_finish(void) */ void ob_flush(void) { - struct iovec vec[2]; + struct rbvec vec[2]; assert(pthread_equal(pthread_self(), dc.thread)); /* DEBUG(__FILE__":%s %d\n", __func__, __LINE__); */ diff --git a/src/outputBuffer_ob_send.h b/src/outputBuffer_ob_send.h index 2a4a84763..d2c99b3f2 100644 --- a/src/outputBuffer_ob_send.h +++ b/src/outputBuffer_ob_send.h @@ -63,7 +63,7 @@ enum dc_action ob_send(void *data, size_t len, float decode_time, mpd_uint16 bit_rate, ReplayGainInfo * rgi) { - struct iovec vec[2]; + struct rbvec vec[2]; struct ob_chunk *c; size_t idx; size_t i, j; @@ -86,9 +86,9 @@ ob_send(void *data, size_t len, } for (i = 0; i < ARRAY_SIZE(vec); i++) { - for (j = 0; j < vec[i].iov_len; j++) { + for (j = 0; j < vec[i].len; j++) { size_t c_len; - idx = vec[i].iov_base - ob.index->buf + j; + idx = vec[i].base - ob.index->buf + j; c = &(ob.chunks[idx]); if (!c->len) { /* populate empty chunk */ diff --git a/src/outputBuffer_xfade.h b/src/outputBuffer_xfade.h index 336a7adc2..50fb062ce 100644 --- a/src/outputBuffer_xfade.h +++ b/src/outputBuffer_xfade.h @@ -5,8 +5,8 @@ #include "audio.h" #include "pcm_utils.h" -static struct ob_chunk *get_chunk(struct iovec vec[2], size_t i); -static size_t calculate_xfade_chunks(struct iovec vec[2]) +static struct ob_chunk *get_chunk(struct rbvec vec[2], size_t i); +static size_t calculate_xfade_chunks(struct rbvec vec[2]) { float xfade_time = ob.xfade_time; /* prevent race conditions */ size_t chunks; @@ -37,7 +37,7 @@ static size_t calculate_xfade_chunks(struct iovec vec[2]) if (chunks > (ob.index->size - ob.bpp_cur)) chunks = ob.index->size - ob.bpp_cur; DEBUG("calculated xfade chunks: %d\n", chunks); - nr = vec[0].iov_len + vec[1].iov_len; + nr = vec[0].len + vec[1].len; if (chunks <= nr) { c = get_chunk(vec, chunks); @@ -64,7 +64,7 @@ static size_t calculate_xfade_chunks(struct iovec vec[2]) return chunks; } -static size_t xfade_chunks_needed(struct iovec vec[2]) +static size_t xfade_chunks_needed(struct rbvec vec[2]) { assert(pthread_equal(ob.thread, pthread_self())); diff --git a/src/ringbuf.c b/src/ringbuf.c index 20a09b326..ec388abf3 100644 --- a/src/ringbuf.c +++ b/src/ringbuf.c @@ -236,7 +236,7 @@ void ringbuf_write_advance(struct ringbuf * rb, size_t cnt) * the readable data is in one segment the second segment has zero * length. */ -size_t ringbuf_get_read_vector(const struct ringbuf * rb, struct iovec * vec) +size_t ringbuf_get_read_vector(const struct ringbuf * rb, struct rbvec * vec) { size_t free_cnt; size_t cnt2; @@ -255,17 +255,17 @@ size_t ringbuf_get_read_vector(const struct ringbuf * rb, struct iovec * vec) * Two part vector: the rest of the buffer after the current * write ptr, plus some from the start of the buffer. */ - vec[0].iov_base = rb->buf + r; - vec[0].iov_len = rb->size - r; - vec[1].iov_base = rb->buf; - vec[1].iov_len = cnt2 & rb->size_mask; + vec[0].base = rb->buf + r; + vec[0].len = rb->size - r; + vec[1].base = rb->buf; + vec[1].len = cnt2 & rb->size_mask; } else { /* Single part vector: just the rest of the buffer */ - vec[0].iov_base = rb->buf + r; - vec[0].iov_len = free_cnt; - vec[1].iov_len = 0; + vec[0].base = rb->buf + r; + vec[0].len = free_cnt; + vec[1].len = 0; } - return vec[0].iov_len + vec[1].iov_len; + return vec[0].len + vec[1].len; } /* @@ -274,7 +274,7 @@ size_t ringbuf_get_read_vector(const struct ringbuf * rb, struct iovec * vec) * the writeable data is in one segment the second segment has zero * length. */ -size_t ringbuf_get_write_vector(const struct ringbuf * rb, struct iovec * vec) +size_t ringbuf_get_write_vector(const struct ringbuf * rb, struct rbvec * vec) { size_t free_cnt; size_t cnt2; @@ -295,15 +295,15 @@ size_t ringbuf_get_write_vector(const struct ringbuf * rb, struct iovec * vec) * Two part vector: the rest of the buffer after the current * write ptr, plus some from the start of the buffer. */ - vec[0].iov_base = rb->buf + w; - vec[0].iov_len = rb->size - w; - vec[1].iov_base = rb->buf; - vec[1].iov_len = cnt2 & rb->size_mask; + vec[0].base = rb->buf + w; + vec[0].len = rb->size - w; + vec[1].base = rb->buf; + vec[1].len = cnt2 & rb->size_mask; } else { - vec[0].iov_base = rb->buf + w; - vec[0].iov_len = free_cnt; - vec[1].iov_len = 0; + vec[0].base = rb->buf + w; + vec[0].len = free_cnt; + vec[1].len = 0; } - return vec[0].iov_len + vec[1].iov_len; + return vec[0].len + vec[1].len; } diff --git a/src/ringbuf.h b/src/ringbuf.h index 93f753897..6225fcadf 100644 --- a/src/ringbuf.h +++ b/src/ringbuf.h @@ -46,6 +46,12 @@ struct ringbuf { size_t size_mask; }; +/* remain binary-compatible with struct iovec declared in : */ +struct rbvec { + unsigned char *base; + size_t len; +}; + /** * Allocates a ringbuffer data structure of a specified size. The * caller must arrange for a call to ringbuf_free() to release @@ -69,7 +75,7 @@ void ringbuf_free(struct ringbuf * rb); /** * Fill a data structure with a description of the current readable * data held in the ringbuffer. This description is returned in a two - * element array of struct iovec. Two elements are needed + * element array of struct rbvec. Two elements are needed * because the data to be read may be split across the end of the * ringbuffer. * @@ -83,16 +89,16 @@ void ringbuf_free(struct ringbuf * rb); * its corresponding @a buf field. * * @param rb a pointer to the ringbuffer structure. - * @param vec a pointer to a 2 element array of struct iovec. + * @param vec a pointer to a 2 element array of struct rbvec. * * @return total number of bytes readable into both vec elements */ -size_t ringbuf_get_read_vector(const struct ringbuf * rb, struct iovec * vec); +size_t ringbuf_get_read_vector(const struct ringbuf * rb, struct rbvec * vec); /** * Fill a data structure with a description of the current writable * space in the ringbuffer. The description is returned in a two - * element array of struct iovec. Two elements are needed + * element array of struct rbvec. Two elements are needed * because the space available for writing may be split across the end * of the ringbuffer. * @@ -106,11 +112,11 @@ size_t ringbuf_get_read_vector(const struct ringbuf * rb, struct iovec * vec); * the corresponding @a buf field. * * @param rb a pointer to the ringbuffer structure. - * @param vec a pointer to a 2 element array of struct iovec. + * @param vec a pointer to a 2 element array of struct rbvec. * * @return total number of bytes writable in both vec elements */ -size_t ringbuf_get_write_vector(const struct ringbuf * rb, struct iovec * vec); +size_t ringbuf_get_write_vector(const struct ringbuf * rb, struct rbvec * vec); /** * Read data from the ringbuffer. -- cgit v1.2.3