pa_shmasyncq *pa_shmasyncq_new(unsigned n_elements, size_t element_size, void *data, int fd[2]) { pa_shmasyncq *l; pa_assert(n_elements > 0); pa_assert(is_power_of_two(n_elements)); pa_assert(element_size > 0); pa_assert(data); pa_assert(fd); l = pa_xnew(pa_shmasyncq, 1); l->data = data; memset(data, 0, PA_SHMASYNCQ_SIZE(n_elements, element_size)); l->data->n_elements = n_elements; l->data->element_size = element_size; if (!(l->read_fdsem = pa_fdsem_new_shm(&d->read_fdsem_data))) { pa_xfree(l); return NULL; } fd[0] = pa_fdsem_get(l->read_fdsem); if (!(l->write_fdsem = pa_fdsem_new(&d->write_fdsem_data, &fd[1]))) { pa_fdsem_free(l->read_fdsem); pa_xfree(l); return NULL; } return l; }
pa_srbchannel* pa_srbchannel_new(pa_mainloop_api *m, pa_mempool *p) { int capacity; int readfd; struct srbheader *srh; pa_srbchannel* sr = pa_xmalloc0(sizeof(pa_srbchannel)); sr->mainloop = m; sr->memblock = pa_memblock_new_pool(p, -1); if (!sr->memblock) goto fail; srh = pa_memblock_acquire(sr->memblock); pa_zero(*srh); sr->rb_read.memory = (uint8_t*) srh + PA_ALIGN(sizeof(*srh)); srh->readbuf_offset = sr->rb_read.memory - (uint8_t*) srh; capacity = (pa_memblock_get_length(sr->memblock) - srh->readbuf_offset) / 2; sr->rb_write.memory = PA_ALIGN_PTR(sr->rb_read.memory + capacity); srh->writebuf_offset = sr->rb_write.memory - (uint8_t*) srh; capacity = PA_MIN(capacity, srh->writebuf_offset - srh->readbuf_offset); pa_log_debug("SHM block is %d bytes, ringbuffer capacity is 2 * %d bytes", (int) pa_memblock_get_length(sr->memblock), capacity); srh->capacity = sr->rb_read.capacity = sr->rb_write.capacity = capacity; sr->rb_read.count = &srh->read_count; sr->rb_write.count = &srh->write_count; sr->sem_read = pa_fdsem_new_shm(&srh->read_semdata); if (!sr->sem_read) goto fail; sr->sem_write = pa_fdsem_new_shm(&srh->write_semdata); if (!sr->sem_write) goto fail; readfd = pa_fdsem_get(sr->sem_read); #ifdef DEBUG_SRBCHANNEL pa_log("Enabling io event on fd %d", readfd); #endif sr->read_event = m->io_new(m, readfd, PA_IO_EVENT_INPUT, semread_cb, sr); m->io_enable(sr->read_event, PA_IO_EVENT_INPUT); return sr; fail: pa_srbchannel_free(sr); return NULL; }
int pa_shmasyncq_get_fd(pa_shmasyncq *q) { pa_assert(q); return pa_fdsem_get(q->write_fdsem); }
int pa_asyncq_write_fd(pa_asyncq *q) { pa_assert(q); return pa_fdsem_get(q->read_fdsem); }
void pa_srbchannel_export(pa_srbchannel *sr, pa_srbchannel_template *t) { t->memblock = sr->memblock; t->readfd = pa_fdsem_get(sr->sem_read); t->writefd = pa_fdsem_get(sr->sem_write); }