static void producer(void *_q) { pa_asyncq *q = _q; int i; for (i = 0; i < 1000; i++) { printf("pushing %i\n", i); pa_asyncq_push(q, PA_UINT_TO_PTR(i+1), 1); } pa_asyncq_push(q, PA_UINT_TO_PTR(-1), TRUE); printf("pushed end\n"); }
void pa_asyncq_post(pa_asyncq*l, void *p) { struct localq *q; pa_assert(l); pa_assert(p); if (flush_postq(l, FALSE)) if (pa_asyncq_push(l, p, FALSE) >= 0) return; /* OK, we couldn't push anything in the queue. So let's queue it * locally and push it later */ if (pa_log_ratelimit()) pa_log_warn("q overrun, queuing locally"); if (!(q = pa_flist_pop(PA_STATIC_FLIST_GET(localq)))) q = pa_xnew(struct localq, 1); q->data = p; PA_LLIST_PREPEND(struct localq, l->localq, q); if (!l->last_localq) l->last_localq = q; return; }
int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *chunk) { struct asyncmsgq_item i; pa_assert(PA_REFCNT_VALUE(a) > 0); i.code = code; i.object = object; i.userdata = (void*) userdata; i.free_cb = NULL; i.ret = -1; i.offset = offset; if (chunk) { pa_assert(chunk->memblock); i.memchunk = *chunk; } else pa_memchunk_reset(&i.memchunk); if (!(i.semaphore = pa_flist_pop(PA_STATIC_FLIST_GET(semaphores)))) i.semaphore = pa_semaphore_new(0); /* This mutex makes the queue multiple-writer safe. This lock is only used on the writing side */ pa_mutex_lock(a->mutex); pa_assert_se(pa_asyncq_push(a->asyncq, &i, true) == 0); pa_mutex_unlock(a->mutex); pa_semaphore_wait(i.semaphore); if (pa_flist_push(PA_STATIC_FLIST_GET(semaphores), i.semaphore) < 0) pa_semaphore_free(i.semaphore); return i.ret; }