SHM: Refactor private allocations

pa_shm_create_rw() is responsible for creating two types of memory:
POSIX shared memory and regular malloc()-ed ones.

A third memory type, memfds, will be added later. Thus to add this
extra shared memory type in a sane manner, refactor private memory
allocations into their own static methods.

Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
This commit is contained in:
Ahmed S. Darwish 2016-03-13 01:01:38 +02:00 committed by David Henningsson
parent b88acd0266
commit 1c3a2bcaf1

View file

@ -101,10 +101,40 @@ static char *segment_name(char *fn, size_t l, unsigned id) {
} }
#endif #endif
static int privatemem_create(pa_shm *m, size_t size) {
pa_assert(m);
pa_assert(size > 0);
m->id = 0;
m->size = size;
m->do_unlink = false;
#ifdef MAP_ANONYMOUS
if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) {
pa_log("mmap() failed: %s", pa_cstrerror(errno));
return -1;
}
#elif defined(HAVE_POSIX_MEMALIGN)
{
int r;
if ((r = posix_memalign(&m->ptr, PA_PAGE_SIZE, size)) < 0) {
pa_log("posix_memalign() failed: %s", pa_cstrerror(r));
return r;
}
}
#else
m->ptr = pa_xmalloc(m->size);
#endif
return 0;
}
int pa_shm_create_rw(pa_shm *m, pa_mem_type_t type, size_t size, mode_t mode) { int pa_shm_create_rw(pa_shm *m, pa_mem_type_t type, size_t size, mode_t mode) {
#ifdef HAVE_SHM_OPEN #ifdef HAVE_SHM_OPEN
char fn[32]; char fn[32];
int fd = -1; int fd = -1;
struct shm_marker *marker;
#endif #endif
pa_assert(m); pa_assert(m);
@ -120,34 +150,12 @@ int pa_shm_create_rw(pa_shm *m, pa_mem_type_t type, size_t size, mode_t mode) {
/* Round up to make it page aligned */ /* Round up to make it page aligned */
size = PA_PAGE_ALIGN(size); size = PA_PAGE_ALIGN(size);
if (!pa_mem_type_is_shared(type)) { m->type = type;
m->id = 0;
m->size = size;
#ifdef MAP_ANONYMOUS if (type == PA_MEM_TYPE_PRIVATE)
if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) { return privatemem_create(m, size);
pa_log("mmap() failed: %s", pa_cstrerror(errno));
goto fail;
}
#elif defined(HAVE_POSIX_MEMALIGN)
{
int r;
if ((r = posix_memalign(&m->ptr, PA_PAGE_SIZE, size)) < 0) {
pa_log("posix_memalign() failed: %s", pa_cstrerror(r));
goto fail;
}
}
#else
m->ptr = pa_xmalloc(m->size);
#endif
m->do_unlink = false;
} else {
#ifdef HAVE_SHM_OPEN #ifdef HAVE_SHM_OPEN
struct shm_marker *marker;
pa_random(&m->id, sizeof(m->id)); pa_random(&m->id, sizeof(m->id));
segment_name(fn, sizeof(fn), m->id); segment_name(fn, sizeof(fn), m->id);
@ -183,9 +191,6 @@ int pa_shm_create_rw(pa_shm *m, pa_mem_type_t type, size_t size, mode_t mode) {
#else #else
goto fail; goto fail;
#endif #endif
}
m->type = type;
return 0; return 0;
@ -201,6 +206,21 @@ fail:
return -1; return -1;
} }
static void privatemem_free(pa_shm *m) {
pa_assert(m);
pa_assert(m->ptr);
pa_assert(m->size > 0);
#ifdef MAP_ANONYMOUS
if (munmap(m->ptr, m->size) < 0)
pa_log("munmap() failed: %s", pa_cstrerror(errno));
#elif defined(HAVE_POSIX_MEMALIGN)
free(m->ptr);
#else
pa_xfree(m->ptr);
#endif
}
void pa_shm_free(pa_shm *m) { void pa_shm_free(pa_shm *m) {
pa_assert(m); pa_assert(m);
pa_assert(m->ptr); pa_assert(m->ptr);
@ -210,16 +230,11 @@ void pa_shm_free(pa_shm *m) {
pa_assert(m->ptr != MAP_FAILED); pa_assert(m->ptr != MAP_FAILED);
#endif #endif
if (!pa_mem_type_is_shared(m->type)) { if (m->type == PA_MEM_TYPE_PRIVATE) {
#ifdef MAP_ANONYMOUS privatemem_free(m);
if (munmap(m->ptr, m->size) < 0) goto finish;
pa_log("munmap() failed: %s", pa_cstrerror(errno)); }
#elif defined(HAVE_POSIX_MEMALIGN)
free(m->ptr);
#else
pa_xfree(m->ptr);
#endif
} else {
#ifdef HAVE_SHM_OPEN #ifdef HAVE_SHM_OPEN
if (munmap(m->ptr, PA_PAGE_ALIGN(m->size)) < 0) if (munmap(m->ptr, PA_PAGE_ALIGN(m->size)) < 0)
pa_log("munmap() failed: %s", pa_cstrerror(errno)); pa_log("munmap() failed: %s", pa_cstrerror(errno));
@ -228,7 +243,6 @@ void pa_shm_free(pa_shm *m) {
char fn[32]; char fn[32];
segment_name(fn, sizeof(fn), m->id); segment_name(fn, sizeof(fn), m->id);
if (shm_unlink(fn) < 0) if (shm_unlink(fn) < 0)
pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno)); pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno));
} }
@ -236,8 +250,8 @@ void pa_shm_free(pa_shm *m) {
/* We shouldn't be here without shm support */ /* We shouldn't be here without shm support */
pa_assert_not_reached(); pa_assert_not_reached();
#endif #endif
}
finish:
pa_zero(*m); pa_zero(*m);
} }