void pa_asyncq_free(pa_asyncq *l, pa_free_cb_t free_cb) { struct localq *q; pa_assert(l); if (free_cb) { void *p; while ((p = pa_asyncq_pop(l, 0))) free_cb(p); } while ((q = l->localq)) { if (free_cb) free_cb(q->data); PA_LLIST_REMOVE(struct localq, l->localq, q); if (pa_flist_push(PA_STATIC_FLIST_GET(localq), q) < 0) pa_xfree(q); } pa_fdsem_free(l->read_fdsem); pa_fdsem_free(l->write_fdsem); pa_xfree(l); }
static void asyncmsgq_free(pa_asyncmsgq *a) { struct asyncmsgq_item *i; pa_assert(a); while ((i = pa_asyncq_pop(a->asyncq, false))) { pa_assert(!i->semaphore); if (i->object) pa_msgobject_unref(i->object); if (i->memchunk.memblock) pa_memblock_unref(i->memchunk.memblock); if (i->free_cb) i->free_cb(i->userdata); if (pa_flist_push(PA_STATIC_FLIST_GET(asyncmsgq), i) < 0) pa_xfree(i); } pa_asyncq_free(a->asyncq, NULL); pa_mutex_free(a->mutex); pa_xfree(a); }
int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **userdata, int64_t *offset, pa_memchunk *chunk, bool wait_op) { pa_assert(PA_REFCNT_VALUE(a) > 0); pa_assert(!a->current); if (!(a->current = pa_asyncq_pop(a->asyncq, wait_op))) { /* pa_log("failure"); */ return -1; } /* pa_log("success"); */ if (code) *code = a->current->code; if (userdata) *userdata = a->current->userdata; if (offset) *offset = a->current->offset; if (object) { if ((*object = a->current->object)) pa_msgobject_assert_ref(*object); } if (chunk) *chunk = a->current->memchunk; /* pa_log_debug("Get q=%p object=%p (%s) code=%i data=%p chunk.length=%lu", */ /* (void*) a, */ /* (void*) a->current->object, */ /* a->current->object ? a->current->object->parent.type_name : NULL, */ /* a->current->code, */ /* (void*) a->current->userdata, */ /* (unsigned long) a->current->memchunk.length); */ return 0; }
/* Called from I/O thread context */ static void cmtspeech_sink_input_reset_dl_stream(struct userdata *u) { cmtspeech_dl_buf_t *buf; pa_assert(u); /* Flush all DL buffers */ pa_memblockq_flush_read(u->dl_memblockq); cmtspeech_dl_sideinfo_flush(u); while ((buf = pa_asyncq_pop(u->cmt_connection.dl_frame_queue, FALSE))) { pa_memchunk cmtchunk; if (0 == cmtspeech_buffer_to_memchunk(u, buf, &cmtchunk)) pa_memblock_unref(cmtchunk.memblock); } }
static void consumer(void *_q) { pa_asyncq *q = _q; void *p; int i; pa_msleep(1000); for (i = 0;; i++) { p = pa_asyncq_pop(q, TRUE); if (p == PA_UINT_TO_PTR(-1)) break; pa_assert(p == PA_UINT_TO_PTR(i+1)); printf("popped %i\n", i); } printf("popped end\n"); }
/*** sink_input callbacks ***/ static int cmtspeech_sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { struct userdata *u; int queue_counter = 0; pa_assert_fp(i); pa_sink_input_assert_ref(i); pa_assert_se(u = i->userdata); pa_assert_fp(chunk); if (u->cmt_connection.dl_frame_queue) { cmtspeech_dl_buf_t *buf; while ((buf = pa_asyncq_pop(u->cmt_connection.dl_frame_queue, FALSE))) { pa_memchunk cmtchunk; if (cmtspeech_buffer_to_memchunk(u, buf, &cmtchunk) < 0) continue; queue_counter++; if (pa_memblockq_push(u->dl_memblockq, &cmtchunk) < 0) { pa_log_debug("Failed to push DL frame to dl_memblockq (len %zu max %zu)", pa_memblockq_get_length(u->dl_memblockq), pa_memblockq_get_maxlength(u->dl_memblockq)); } else { cmtspeech_dl_sideinfo_push(buf->spc_flags, cmtchunk.length, u); } pa_memblock_unref(cmtchunk.memblock); } } /* More than one DL frame in queue means that sink has not asked for more * data for over 20ms and something may be wrong. */ if (queue_counter > 1) { pa_log_info("%d frames found from queue (dl buf size %zu)", queue_counter, pa_memblockq_get_length(u->dl_memblockq)); } if (pa_memblockq_get_length(u->dl_memblockq) > 3*u->dl_frame_size) { size_t drop_bytes = pa_memblockq_get_length(u->dl_memblockq) - 3*u->dl_frame_size; pa_memblockq_drop(u->dl_memblockq, drop_bytes); cmtspeech_dl_sideinfo_drop(u, drop_bytes); pa_log_debug("Too much data in DL buffer dropped %zu bytes", drop_bytes); } pa_assert_fp((pa_memblockq_get_length(u->dl_memblockq) % u->dl_frame_size) == 0); if (util_memblockq_to_chunk(u->core->mempool, u->dl_memblockq, chunk, u->dl_frame_size)) { ONDEBUG_TOKENS(fprintf(stderr, "d")); cmtspeech_dl_sideinfo_forward(u); } else { if (u->cmt_connection.first_dl_frame_received) pa_log_debug("No DL audio: %zu bytes in queue %zu needed", pa_memblockq_get_length(u->dl_memblockq), u->dl_frame_size); cmtspeech_dl_sideinfo_bogus(u); pa_silence_memchunk_get(&u->core->silence_cache, u->core->mempool, chunk, &u->ss, u->dl_frame_size); } return 0; }