32 struct xmms_ringbuf_St {
38 guint buffer_size_usable;
40 guint rd_index, wr_index;
45 GCond *free_cond, *used_cond, *eos_cond;
48 typedef struct xmms_ringbuf_hotspot_St {
50 gboolean (*callback) (
void *);
51 void (*destroy) (
void *);
62 g_return_val_if_fail (ringbuf, 0);
64 return ringbuf->buffer_size_usable;
78 g_return_val_if_fail (size > 0, NULL);
79 g_return_val_if_fail (size < G_MAXUINT, NULL);
87 ringbuf->buffer_size_usable = size;
88 ringbuf->buffer_size = size + 1;
89 ringbuf->buffer = g_malloc (ringbuf->buffer_size);
91 ringbuf->free_cond = g_cond_new ();
92 ringbuf->used_cond = g_cond_new ();
93 ringbuf->eos_cond = g_cond_new ();
95 ringbuf->hotspots = g_queue_new ();
106 g_return_if_fail (ringbuf);
108 g_cond_free (ringbuf->eos_cond);
109 g_cond_free (ringbuf->used_cond);
110 g_cond_free (ringbuf->free_cond);
112 g_queue_free (ringbuf->hotspots);
113 g_free (ringbuf->buffer);
123 g_return_if_fail (ringbuf);
125 ringbuf->rd_index = 0;
126 ringbuf->wr_index = 0;
128 while (!g_queue_is_empty (ringbuf->hotspots)) {
130 hs = g_queue_pop_head (ringbuf->hotspots);
132 hs->destroy (hs->arg);
135 g_cond_signal (ringbuf->free_cond);
144 g_return_val_if_fail (ringbuf, 0);
146 return ringbuf->buffer_size_usable -
156 g_return_val_if_fail (ringbuf, 0);
158 if (ringbuf->wr_index >= ringbuf->rd_index) {
159 return ringbuf->wr_index - ringbuf->rd_index;
162 return ringbuf->buffer_size - (ringbuf->rd_index - ringbuf->wr_index);
168 guint to_read, r = 0, cnt, tmp;
173 while (!g_queue_is_empty (ringbuf->hotspots)) {
175 if (hs->pos != ringbuf->rd_index) {
177 to_read =
MIN (to_read,
178 (hs->pos - ringbuf->rd_index + ringbuf->buffer_size)
179 % ringbuf->buffer_size);
183 (void) g_queue_pop_head (ringbuf->hotspots);
184 ok = hs->callback (hs->arg);
186 hs->destroy (hs->arg);
197 tmp = ringbuf->rd_index;
199 while (to_read > 0) {
200 cnt =
MIN (to_read, ringbuf->buffer_size - tmp);
201 memcpy (data, ringbuf->buffer + tmp, cnt);
202 tmp = (tmp + cnt) % ringbuf->buffer_size;
226 g_return_val_if_fail (ringbuf, 0);
227 g_return_val_if_fail (data, 0);
228 g_return_val_if_fail (len > 0, 0);
230 r = read_bytes (ringbuf, (guint8 *) data, len);
232 ringbuf->rd_index += r;
233 ringbuf->rd_index %= ringbuf->buffer_size;
236 g_cond_broadcast (ringbuf->free_cond);
251 g_return_val_if_fail (ringbuf, 0);
252 g_return_val_if_fail (data, 0);
253 g_return_val_if_fail (len > 0, 0);
254 g_return_val_if_fail (len <= ringbuf->buffer_size_usable, 0);
256 return read_bytes (ringbuf, (guint8 *) data, len);
266 guint len, GMutex *mtx)
271 g_return_val_if_fail (ringbuf, 0);
272 g_return_val_if_fail (data, 0);
273 g_return_val_if_fail (len > 0, 0);
274 g_return_val_if_fail (mtx, 0);
279 if (r == len || ringbuf->eos) {
283 g_cond_wait (ringbuf->used_cond, mtx);
296 guint len, GMutex *mtx)
298 g_return_val_if_fail (ringbuf, 0);
299 g_return_val_if_fail (data, 0);
300 g_return_val_if_fail (len > 0, 0);
301 g_return_val_if_fail (len <= ringbuf->buffer_size_usable, 0);
302 g_return_val_if_fail (mtx, 0);
324 guint to_write, w = 0, cnt;
325 const guint8 *src = data;
327 g_return_val_if_fail (ringbuf, 0);
328 g_return_val_if_fail (data, 0);
329 g_return_val_if_fail (len > 0, 0);
333 while (to_write > 0) {
334 cnt =
MIN (to_write, ringbuf->buffer_size - ringbuf->wr_index);
335 memcpy (ringbuf->buffer + ringbuf->wr_index, src + w, cnt);
336 ringbuf->wr_index = (ringbuf->wr_index + cnt) % ringbuf->buffer_size;
342 g_cond_broadcast (ringbuf->used_cond);
354 guint len, GMutex *mtx)
357 const guint8 *src = data;
359 g_return_val_if_fail (ringbuf, 0);
360 g_return_val_if_fail (data, 0);
361 g_return_val_if_fail (len > 0, 0);
362 g_return_val_if_fail (mtx, 0);
366 if (w == len || ringbuf->eos) {
370 g_cond_wait (ringbuf->free_cond, mtx);
382 g_return_if_fail (ringbuf);
383 g_return_if_fail (len > 0);
384 g_return_if_fail (len <= ringbuf->buffer_size_usable);
385 g_return_if_fail (mtx);
388 g_cond_wait (ringbuf->free_cond, mtx);
399 g_return_if_fail (ringbuf);
400 g_return_if_fail (len > 0);
401 g_return_if_fail (len <= ringbuf->buffer_size_usable);
402 g_return_if_fail (mtx);
405 g_cond_wait (ringbuf->used_cond, mtx);
418 g_return_val_if_fail (ringbuf, TRUE);
429 g_return_if_fail (ringbuf);
434 g_cond_broadcast (ringbuf->eos_cond);
435 g_cond_broadcast (ringbuf->used_cond);
436 g_cond_broadcast (ringbuf->free_cond);
447 g_return_if_fail (ringbuf);
448 g_return_if_fail (mtx);
451 g_cond_wait (ringbuf->eos_cond, mtx);
465 g_return_if_fail (ringbuf);
468 hs->pos = ringbuf->wr_index;
470 hs->destroy = destroy;
473 g_queue_push_tail (ringbuf->hotspots, hs);
struct xmms_ringbuf_St xmms_ringbuf_t
gboolean xmms_ringbuf_iseos(const xmms_ringbuf_t *ringbuf)
Tell if the ringbuffer is EOS.
guint xmms_ringbuf_read_wait(xmms_ringbuf_t *ringbuf, gpointer data, guint len, GMutex *mtx)
Same as xmms_ringbuf_read but blocks until you have all the data you want.
guint xmms_ringbuf_peek(xmms_ringbuf_t *ringbuf, gpointer data, guint len)
Same as xmms_ringbuf_read but does not advance in the buffer after the data has been read...
void xmms_ringbuf_wait_free(const xmms_ringbuf_t *ringbuf, guint len, GMutex *mtx)
Block until we have free space in the ringbuffer.
guint xmms_ringbuf_size(xmms_ringbuf_t *ringbuf)
The usable size of the ringbuffer.
guint xmms_ringbuf_peek_wait(xmms_ringbuf_t *ringbuf, gpointer data, guint len, GMutex *mtx)
Same as xmms_ringbuf_peek but blocks until you have all the data you want.
guint xmms_ringbuf_write(xmms_ringbuf_t *ringbuf, gconstpointer data, guint len)
Write data to the ringbuffer.
guint xmms_ringbuf_bytes_free(const xmms_ringbuf_t *ringbuf)
Number of bytes free in the ringbuffer.
guint xmms_ringbuf_bytes_used(const xmms_ringbuf_t *ringbuf)
Number of bytes used in the buffer.
void xmms_ringbuf_wait_used(const xmms_ringbuf_t *ringbuf, guint len, GMutex *mtx)
Block until we have used space in the buffer.
guint xmms_ringbuf_read(xmms_ringbuf_t *ringbuf, gpointer data, guint len)
Reads data from the ringbuffer.
xmms_ringbuf_t * xmms_ringbuf_new(guint size)
Allocate a new ringbuffer.
void xmms_ringbuf_wait_eos(const xmms_ringbuf_t *ringbuf, GMutex *mtx)
Block until we are EOSed.
struct xmms_ringbuf_hotspot_St xmms_ringbuf_hotspot_t
guint xmms_ringbuf_write_wait(xmms_ringbuf_t *ringbuf, gconstpointer data, guint len, GMutex *mtx)
Same as xmms_ringbuf_write but blocks until there is enough free space.
void xmms_ringbuf_clear(xmms_ringbuf_t *ringbuf)
Clear the ringbuffers data.
void xmms_ringbuf_set_eos(xmms_ringbuf_t *ringbuf, gboolean eos)
Set EOS flag on ringbuffer.
void xmms_ringbuf_destroy(xmms_ringbuf_t *ringbuf)
Free all memory used by the ringbuffer.
void xmms_ringbuf_hotspot_set(xmms_ringbuf_t *ringbuf, gboolean(*cb)(void *), void(*destroy)(void *), void *arg)