pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min) { pa_memblock *n; size_t l; void *tdata, *sdata; pa_assert(c); pa_assert(c->memblock); if (pa_memblock_ref_is_one(c->memblock) && !pa_memblock_is_read_only(c->memblock) && pa_memblock_get_length(c->memblock) >= c->index+min) return c; l = PA_MAX(c->length, min); n = pa_memblock_new(pa_memblock_get_pool(c->memblock), l); sdata = pa_memblock_acquire(c->memblock); tdata = pa_memblock_acquire(n); memcpy(tdata, (uint8_t*) sdata + c->index, c->length); pa_memblock_release(c->memblock); pa_memblock_release(n); pa_memblock_unref(c->memblock); c->memblock = n; c->index = 0; return c; }
static void handle_srbchannel_memblock(pa_context *c, pa_memblock *memblock) { pa_srbchannel *sr; pa_tagstruct *t; pa_assert(c); /* Memblock sanity check */ if (!memblock) { pa_context_fail(c, PA_ERR_PROTOCOL); return; } else if (pa_memblock_is_read_only(memblock)) { pa_context_fail(c, PA_ERR_PROTOCOL); return; } else if (pa_memblock_is_ours(memblock)) { pa_context_fail(c, PA_ERR_PROTOCOL); return; } /* Create the srbchannel */ c->srb_template.memblock = memblock; pa_memblock_ref(memblock); sr = pa_srbchannel_new_from_template(c->mainloop, &c->srb_template); if (!sr) { pa_log_warn("Failed to create srbchannel from template"); c->srb_template.readfd = -1; c->srb_template.writefd = -1; pa_memblock_unref(c->srb_template.memblock); c->srb_template.memblock = NULL; return; } /* Ack the enable command */ t = pa_tagstruct_new(); pa_tagstruct_putu32(t, PA_COMMAND_ENABLE_SRBCHANNEL); pa_tagstruct_putu32(t, c->srb_setup_tag); pa_pstream_send_tagstruct(c->pstream, t); /* ...and switch over */ pa_pstream_set_srbchannel(c->pstream, sr); }