static void asyncmsgq_read_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { pa_thread_mq *q = userdata; pa_asyncmsgq *aq; pa_assert(pa_asyncmsgq_read_fd(q->outq) == fd); pa_assert(events == PA_IO_EVENT_INPUT); pa_asyncmsgq_ref(aq = q->outq); pa_asyncmsgq_read_after_poll(aq); for (;;) { pa_msgobject *object; int code; void *data; int64_t offset; pa_memchunk chunk; /* Check whether there is a message for us to process */ while (pa_asyncmsgq_get(aq, &object, &code, &data, &offset, &chunk, 0) >= 0) { int ret; ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(aq, ret); } if (pa_asyncmsgq_read_before_poll(aq) == 0) break; } pa_asyncmsgq_unref(aq); }
int main(int argc, char *argv[]) { pa_asyncmsgq *q; pa_thread *t; pa_assert_se(q = pa_asyncmsgq_new(0)); pa_assert_se(t = pa_thread_new("test", the_thread, q)); pa_log_info("Operation A post"); pa_asyncmsgq_post(q, NULL, OPERATION_A, NULL, 0, NULL, NULL); pa_thread_yield(); pa_log_info("Operation B post"); pa_asyncmsgq_post(q, NULL, OPERATION_B, NULL, 0, NULL, NULL); pa_thread_yield(); pa_log_info("Operation C send"); pa_asyncmsgq_send(q, NULL, OPERATION_C, NULL, 0, NULL); pa_thread_yield(); pa_log_info("Quit post"); pa_asyncmsgq_post(q, NULL, QUIT, NULL, 0, NULL, NULL); pa_thread_free(t); pa_asyncmsgq_unref(q); return 0; }
void pa__done(pa_module*m) { struct userdata *u; pa_assert(m); if (!(u = m->userdata)) return; if (u->client) jack_client_close(u->client); if (u->sink) pa_sink_unlink(u->sink); if (u->thread) { pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } pa_thread_mq_done(&u->thread_mq); if (u->sink) pa_sink_unref(u->sink); if (u->rtpoll_item) pa_rtpoll_item_free(u->rtpoll_item); if (u->jack_msgq) pa_asyncmsgq_unref(u->jack_msgq); if (u->rtpoll) pa_rtpoll_free(u->rtpoll); pa_xfree(u); }
void pa_asyncmsgq_flush(pa_asyncmsgq *a, bool run) { pa_assert(PA_REFCNT_VALUE(a) > 0); for (;;) { pa_msgobject *object; int code; void *data; int64_t offset; pa_memchunk chunk; int ret; if (pa_asyncmsgq_get(a, &object, &code, &data, &offset, &chunk, false) < 0) return; if (!run) { pa_asyncmsgq_done(a, -1); continue; } pa_asyncmsgq_ref(a); ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(a, ret); pa_asyncmsgq_unref(a); } }
int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) { int c; pa_assert(PA_REFCNT_VALUE(a) > 0); pa_asyncmsgq_ref(a); do { pa_msgobject *o; void *data; int64_t offset; pa_memchunk chunk; int ret; if (pa_asyncmsgq_get(a, &o, &c, &data, &offset, &chunk, true) < 0) return -1; ret = pa_asyncmsgq_dispatch(o, c, data, offset, &chunk); pa_asyncmsgq_done(a, ret); } while (c != code); pa_asyncmsgq_unref(a); return 0; }
void pa_thread_mq_done(pa_thread_mq *q) { pa_assert(q); /* Since we are called from main context we can be sure that the * inq is empty. However, the outq might still contain messages * for the main loop, which we need to dispatch (e.g. release * msgs, other stuff). Hence do so if we aren't currently * dispatching anyway. */ if (!pa_asyncmsgq_dispatching(q->outq)) pa_asyncmsgq_flush(q->outq, true); q->mainloop->io_free(q->read_event); q->mainloop->io_free(q->write_event); q->read_event = q->write_event = NULL; pa_asyncmsgq_unref(q->inq); pa_asyncmsgq_unref(q->outq); q->inq = q->outq = NULL; q->mainloop = NULL; }
void pa__done(pa_module*m) { struct userdata *u; pa_assert(m); if (!(u = m->userdata)) return; teardown(u); if (u->memblockq) pa_memblockq_free(u->memblockq); if (u->asyncmsgq) pa_asyncmsgq_unref(u->asyncmsgq); pa_xfree(u); }
int pa_asyncmsgq_process_one(pa_asyncmsgq *a) { pa_msgobject *object; int code; void *data; pa_memchunk chunk; int64_t offset; int ret; pa_assert(PA_REFCNT_VALUE(a) > 0); if (pa_asyncmsgq_get(a, &object, &code, &data, &offset, &chunk, false) < 0) return 0; pa_asyncmsgq_ref(a); ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(a, ret); pa_asyncmsgq_unref(a); return 1; }