mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
memblock, pstream: Allow send/receive of remote writable memblocks
The shared ringbuffer memblock must be writable by both sides. This makes it possible to send such a memblock over a pstream without the "both sides writable" information getting lost. Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
parent
613177919f
commit
710c4b39af
3 changed files with 62 additions and 16 deletions
|
|
@ -97,6 +97,7 @@ struct pa_memimport_segment {
|
|||
pa_shm memory;
|
||||
pa_memtrap *trap;
|
||||
unsigned n_blocks;
|
||||
bool writable;
|
||||
};
|
||||
|
||||
/* A collection of multiple segments */
|
||||
|
|
@ -146,6 +147,7 @@ struct pa_mempool {
|
|||
pa_shm memory;
|
||||
size_t block_size;
|
||||
unsigned n_blocks;
|
||||
bool is_remote_writable;
|
||||
|
||||
pa_atomic_t n_init;
|
||||
|
||||
|
|
@ -302,6 +304,19 @@ static struct mempool_slot* mempool_slot_by_ptr(pa_mempool *p, void *ptr) {
|
|||
return (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (idx * p->block_size));
|
||||
}
|
||||
|
||||
/* No lock necessary */
|
||||
bool pa_mempool_is_remote_writable(pa_mempool *p) {
|
||||
pa_assert(p);
|
||||
return p->is_remote_writable;
|
||||
}
|
||||
|
||||
/* No lock necessary */
|
||||
void pa_mempool_set_is_remote_writable(pa_mempool *p, bool writable) {
|
||||
pa_assert(p);
|
||||
pa_assert(!writable || pa_mempool_is_shared(p));
|
||||
p->is_remote_writable = writable;
|
||||
}
|
||||
|
||||
/* No lock necessary */
|
||||
pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) {
|
||||
pa_memblock *b = NULL;
|
||||
|
|
@ -415,6 +430,14 @@ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, pa_free
|
|||
return b;
|
||||
}
|
||||
|
||||
/* No lock necessary */
|
||||
bool pa_memblock_is_ours(pa_memblock *b) {
|
||||
pa_assert(b);
|
||||
pa_assert(PA_REFCNT_VALUE(b) > 0);
|
||||
|
||||
return b->type != PA_MEMBLOCK_IMPORTED;
|
||||
}
|
||||
|
||||
/* No lock necessary */
|
||||
bool pa_memblock_is_read_only(pa_memblock *b) {
|
||||
pa_assert(b);
|
||||
|
|
@ -905,7 +928,7 @@ pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void
|
|||
static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i);
|
||||
|
||||
/* Should be called locked */
|
||||
static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) {
|
||||
static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id, bool writable) {
|
||||
pa_memimport_segment* seg;
|
||||
|
||||
if (pa_hashmap_size(i->segments) >= PA_MEMIMPORT_SEGMENTS_MAX)
|
||||
|
|
@ -913,11 +936,12 @@ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) {
|
|||
|
||||
seg = pa_xnew0(pa_memimport_segment, 1);
|
||||
|
||||
if (pa_shm_attach(&seg->memory, shm_id, false) < 0) {
|
||||
if (pa_shm_attach(&seg->memory, shm_id, writable) < 0) {
|
||||
pa_xfree(seg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
seg->writable = writable;
|
||||
seg->import = i;
|
||||
seg->trap = pa_memtrap_add(seg->memory.ptr, seg->memory.size);
|
||||
|
||||
|
|
@ -973,7 +997,8 @@ void pa_memimport_free(pa_memimport *i) {
|
|||
}
|
||||
|
||||
/* Self-locked */
|
||||
pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_id, size_t offset, size_t size) {
|
||||
pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_id,
|
||||
size_t offset, size_t size, bool writable) {
|
||||
pa_memblock *b = NULL;
|
||||
pa_memimport_segment *seg;
|
||||
|
||||
|
|
@ -990,9 +1015,14 @@ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_i
|
|||
goto finish;
|
||||
|
||||
if (!(seg = pa_hashmap_get(i->segments, PA_UINT32_TO_PTR(shm_id))))
|
||||
if (!(seg = segment_attach(i, shm_id)))
|
||||
if (!(seg = segment_attach(i, shm_id, writable)))
|
||||
goto finish;
|
||||
|
||||
if (writable != seg->writable) {
|
||||
pa_log("Cannot open segment - writable status changed!");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (offset+size > seg->memory.size)
|
||||
goto finish;
|
||||
|
||||
|
|
@ -1002,7 +1032,7 @@ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_i
|
|||
PA_REFCNT_INIT(b);
|
||||
b->pool = i->pool;
|
||||
b->type = PA_MEMBLOCK_IMPORTED;
|
||||
b->read_only = true;
|
||||
b->read_only = !writable;
|
||||
b->is_silence = false;
|
||||
pa_atomic_ptr_store(&b->data, (uint8_t*) seg->memory.ptr + offset);
|
||||
b->length = size;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue