コード例 #1
0
ファイル: fdsem.c プロジェクト: felfert/pulseaudio
pa_fdsem *pa_fdsem_new(void) {
    pa_fdsem *f;

    f = pa_xmalloc(PA_ALIGN(sizeof(pa_fdsem)) + PA_ALIGN(sizeof(pa_fdsem_data)));

#ifdef HAVE_SYS_EVENTFD_H
    if ((f->efd = eventfd(0, EFD_CLOEXEC)) >= 0)
        f->fds[0] = f->fds[1] = -1;
    else
#endif
    {
        if (pa_pipe_cloexec(f->fds) < 0) {
            pa_xfree(f);
            return NULL;
        }
    }

    f->data = (pa_fdsem_data*) ((uint8_t*) f + PA_ALIGN(sizeof(pa_fdsem)));

    pa_atomic_store(&f->data->waiting, 0);
    pa_atomic_store(&f->data->signalled, 0);
    pa_atomic_store(&f->data->in_pipe, 0);

    return f;
}
コード例 #2
0
ファイル: auth-cookie.c プロジェクト: Distrotech/pulseaudio
pa_auth_cookie* pa_auth_cookie_get(pa_core *core, const char *cn, bool create, size_t size) {
    pa_auth_cookie *c;
    char *t;

    pa_assert(core);
    pa_assert(size > 0);

    t = pa_sprintf_malloc("auth-cookie%s%s", cn ? "@" : "", cn ? cn : "");

    if ((c = pa_shared_get(core, t))) {

        pa_xfree(t);

        if (c->size != size)
            return NULL;

        return pa_auth_cookie_ref(c);
    }

    c = pa_xmalloc(PA_ALIGN(sizeof(pa_auth_cookie)) + size);
    PA_REFCNT_INIT(c);
    c->core = core;
    c->name = t;
    c->size = size;

    pa_assert_se(pa_shared_set(core, t, c) >= 0);

    if (pa_authkey_load(cn, create, (uint8_t*) c + PA_ALIGN(sizeof(pa_auth_cookie)), size) < 0) {
        pa_auth_cookie_unref(c);
        return NULL;
    }

    return c;
}
コード例 #3
0
ファイル: memblock.c プロジェクト: DryakhlyyZlodey/pulseaudio
/* No lock necessary */
pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) {
    pa_memblock *b = NULL;
    struct mempool_slot *slot;
    static int mempool_disable = 0;

    pa_assert(p);
    pa_assert(length);

    if (mempool_disable == 0)
        mempool_disable = getenv("PULSE_MEMPOOL_DISABLE") ? 1 : -1;

    if (mempool_disable > 0)
        return NULL;

    /* If -1 is passed as length we choose the size for the caller: we
     * take the largest size that fits in one of our slots. */

    if (length == (size_t) -1)
        length = pa_mempool_block_size_max(p);

    if (p->block_size >= PA_ALIGN(sizeof(pa_memblock)) + length) {

        if (!(slot = mempool_allocate_slot(p)))
            return NULL;

        b = mempool_slot_data(slot);
        b->type = PA_MEMBLOCK_POOL;
        pa_atomic_ptr_store(&b->data, (uint8_t*) b + PA_ALIGN(sizeof(pa_memblock)));

    } else if (p->block_size >= length) {

        if (!(slot = mempool_allocate_slot(p)))
            return NULL;

        if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks))))
            b = pa_xnew(pa_memblock, 1);

        b->type = PA_MEMBLOCK_POOL_EXTERNAL;
        pa_atomic_ptr_store(&b->data, mempool_slot_data(slot));

    } else {
        pa_log_debug("Memory block too large for pool: %lu > %lu", (unsigned long) length, (unsigned long) p->block_size);
        pa_atomic_inc(&p->stat.n_too_large_for_pool);
        return NULL;
    }

    PA_REFCNT_INIT(b);
    b->pool = p;
    b->read_only = b->is_silence = false;
    b->length = length;
    pa_atomic_store(&b->n_acquired, 0);
    pa_atomic_store(&b->please_signal, 0);

    stat_add(b);
    return b;
}
コード例 #4
0
ファイル: strbuf.c プロジェクト: Distrotech/pulseaudio
/* The following is based on an example from the GNU libc documentation */
size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) {
    size_t size = 100;
    struct chunk *c = NULL;

    pa_assert(sb);
    pa_assert(format);

    for(;;) {
        va_list ap;
        int r;

        c = pa_xrealloc(c, PA_ALIGN(sizeof(struct chunk)) + size);

        va_start(ap, format);
        r = vsnprintf(CHUNK_TO_TEXT(c), size, format, ap);
        CHUNK_TO_TEXT(c)[size-1] = 0;
        va_end(ap);

        if (r > -1 && (size_t) r < size) {
            c->length = (size_t) r;
            append(sb, c);
            return (size_t) r;
        }

        if (r > -1)    /* glibc 2.1 */
            size = (size_t) r+1;
        else           /* glibc 2.0 */
            size *= 2;
    }
}
コード例 #5
0
ファイル: auth-cookie.c プロジェクト: Distrotech/pulseaudio
const uint8_t* pa_auth_cookie_read(pa_auth_cookie *c, size_t size) {
    pa_assert(c);
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
    pa_assert(c->size == size);

    return (const uint8_t*) c + PA_ALIGN(sizeof(pa_auth_cookie));
}
コード例 #6
0
ファイル: memblock.c プロジェクト: thewb/mokoiax
pa_mempool* pa_mempool_new(int shared) {
    pa_mempool *p;

    p = pa_xnew(pa_mempool, 1);

    p->mutex = pa_mutex_new(TRUE, TRUE);
    p->semaphore = pa_semaphore_new(0);

    p->block_size = PA_PAGE_ALIGN(PA_MEMPOOL_SLOT_SIZE);
    if (p->block_size < PA_PAGE_SIZE)
        p->block_size = PA_PAGE_SIZE;

    p->n_blocks = PA_MEMPOOL_SLOTS_MAX;

    pa_assert(p->block_size > PA_ALIGN(sizeof(struct mempool_slot)));

    if (pa_shm_create_rw(&p->memory, p->n_blocks * p->block_size, shared, 0700) < 0) {
        pa_xfree(p);
        return NULL;
    }

    memset(&p->stat, 0, sizeof(p->stat));
    pa_atomic_store(&p->n_init, 0);

    PA_LLIST_HEAD_INIT(pa_memimport, p->imports);
    PA_LLIST_HEAD_INIT(pa_memexport, p->exports);

    p->free_slots = pa_flist_new(p->n_blocks*2);

    return p;
}
コード例 #7
0
ファイル: memblock.c プロジェクト: thewb/mokoiax
/* No lock necessary. This function is not multiple caller safe! */
static void memblock_make_local(pa_memblock *b) {
    pa_assert(b);

    pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]);

    if (b->length <= b->pool->block_size - PA_ALIGN(sizeof(struct mempool_slot))) {
        struct mempool_slot *slot;

        if ((slot = mempool_allocate_slot(b->pool))) {
            void *new_data;
            /* We can move it into a local pool, perfect! */

            new_data = mempool_slot_data(slot);
            memcpy(new_data, pa_atomic_ptr_load(&b->data), b->length);
            pa_atomic_ptr_store(&b->data, new_data);

            b->type = PA_MEMBLOCK_POOL_EXTERNAL;
            b->read_only = 0;

            goto finish;
        }
    }

    /* Humm, not enough space in the pool, so lets allocate the memory with malloc() */
    b->per_type.user.free_cb = pa_xfree;
    pa_atomic_ptr_store(&b->data, pa_xmemdup(pa_atomic_ptr_load(&b->data), b->length));

    b->type = PA_MEMBLOCK_USER;
    b->read_only = 0;

finish:
    pa_atomic_inc(&b->pool->stat.n_allocated_by_type[b->type]);
    pa_atomic_inc(&b->pool->stat.n_accumulated_by_type[b->type]);
    memblock_wait(b);
}
コード例 #8
0
ファイル: asyncq.c プロジェクト: KimT/pulseaudio_kt
pa_asyncq *pa_asyncq_new(unsigned size) {
    pa_asyncq *l;

    if (!size)
        size = ASYNCQ_SIZE;

    pa_assert(pa_is_power_of_two(size));

    l = pa_xmalloc0(PA_ALIGN(sizeof(pa_asyncq)) + (sizeof(pa_atomic_ptr_t) * size));

    l->size = size;

    PA_LLIST_HEAD_INIT(struct localq, l->localq);
    l->last_localq = NULL;
    l->waiting_for_post = FALSE;

    if (!(l->read_fdsem = pa_fdsem_new())) {
        pa_xfree(l);
        return NULL;
    }

    if (!(l->write_fdsem = pa_fdsem_new())) {
        pa_fdsem_free(l->read_fdsem);
        pa_xfree(l);
        return NULL;
    }

    return l;
}
コード例 #9
0
ファイル: srbchannel.c プロジェクト: Distrotech/pulseaudio
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;
}
コード例 #10
0
ファイル: memblock.c プロジェクト: thewb/mokoiax
/* No lock necessary */
void pa_mempool_vacuum(pa_mempool *p) {
    struct mempool_slot *slot;
    pa_flist *list;

    pa_assert(p);

    list = pa_flist_new(p->n_blocks*2);

    while ((slot = pa_flist_pop(p->free_slots)))
        while (pa_flist_push(list, slot) < 0)
            ;

    while ((slot = pa_flist_pop(list))) {
        pa_shm_punch(&p->memory,
                     (uint8_t*) slot - (uint8_t*) p->memory.ptr + PA_ALIGN(sizeof(struct mempool_slot)),
                     p->block_size - PA_ALIGN(sizeof(struct mempool_slot)));

        while (pa_flist_push(p->free_slots, slot))
            ;
    }

    pa_flist_free(list, NULL);
}
コード例 #11
0
ファイル: idxset.c プロジェクト: BYSTROSTREL/pulseaudio
pa_idxset* pa_idxset_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func) {
    pa_idxset *s;

    s = pa_xmalloc0(PA_ALIGN(sizeof(pa_idxset)) + NBUCKETS*2*sizeof(struct idxset_entry*));

    s->hash_func = hash_func ? hash_func : pa_idxset_trivial_hash_func;
    s->compare_func = compare_func ? compare_func : pa_idxset_trivial_compare_func;

    s->current_index = 0;
    s->n_entries = 0;
    s->iterate_list_head = s->iterate_list_tail = NULL;

    return s;
}
コード例 #12
0
ファイル: shm.c プロジェクト: Elemecca/pulseaudio
int pa_shm_attach(pa_shm *m, unsigned id, bool writable) {
    char fn[32];
    int fd = -1;
    int prot;
    struct stat st;

    pa_assert(m);

    segment_name(fn, sizeof(fn), m->id = id);

    if ((fd = shm_open(fn, writable ? O_RDWR : O_RDONLY, 0)) < 0) {
        if (errno != EACCES && errno != ENOENT)
            pa_log("shm_open() failed: %s", pa_cstrerror(errno));
        goto fail;
    }

    if (fstat(fd, &st) < 0) {
        pa_log("fstat() failed: %s", pa_cstrerror(errno));
        goto fail;
    }

    if (st.st_size <= 0 ||
        st.st_size > (off_t) (MAX_SHM_SIZE+SHM_MARKER_SIZE) ||
        PA_ALIGN((size_t) st.st_size) != (size_t) st.st_size) {
        pa_log("Invalid shared memory segment size");
        goto fail;
    }

    m->size = (size_t) st.st_size;

    prot = writable ? PROT_READ | PROT_WRITE : PROT_READ;
    if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), prot, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
        pa_log("mmap() failed: %s", pa_cstrerror(errno));
        goto fail;
    }

    m->do_unlink = false;
    m->shared = true;

    pa_assert_se(pa_close(fd) == 0);

    return 0;

fail:
    if (fd >= 0)
        pa_close(fd);

    return -1;
}
コード例 #13
0
ファイル: strbuf.c プロジェクト: Distrotech/pulseaudio
/* Append up to l bytes of a string to the string buffer */
void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t l) {
    struct chunk *c;

    pa_assert(sb);
    pa_assert(t);

    if (!l)
        return;

    c = pa_xmalloc(PA_ALIGN(sizeof(struct chunk)) + l);
    c->length = l;
    memcpy(CHUNK_TO_TEXT(c), t, l);

    append(sb, c);
}
コード例 #14
0
ファイル: memblock.c プロジェクト: DryakhlyyZlodey/pulseaudio
/* No lock necessary */
static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) {
    pa_memblock *b;

    pa_assert(p);
    pa_assert(length);

    /* If -1 is passed as length we choose the size for the caller. */

    if (length == (size_t) -1)
        length = pa_mempool_block_size_max(p);

    b = pa_xmalloc(PA_ALIGN(sizeof(pa_memblock)) + length);
    PA_REFCNT_INIT(b);
    b->pool = p;
    b->type = PA_MEMBLOCK_APPENDED;
    b->read_only = b->is_silence = false;
    pa_atomic_ptr_store(&b->data, (uint8_t*) b + PA_ALIGN(sizeof(pa_memblock)));
    b->length = length;
    pa_atomic_store(&b->n_acquired, 0);
    pa_atomic_store(&b->please_signal, 0);

    stat_add(b);
    return b;
}
コード例 #15
0
ファイル: shm.c プロジェクト: almosthappy4u/PulseAudio-UCM
int pa_shm_attach_ro(pa_shm *m, unsigned id) {
    char fn[32];
    int fd = -1;
    struct stat st;

    pa_assert(m);

    segment_name(fn, sizeof(fn), m->id = id);

    if ((fd = shm_open(fn, O_RDONLY, 0)) < 0) {
        if (errno != EACCES)
            pa_log("shm_open() failed: %s", pa_cstrerror(errno));
        goto fail;
    }

    if (fstat(fd, &st) < 0) {
        pa_log("fstat() failed: %s", pa_cstrerror(errno));
        goto fail;
    }

    if (st.st_size <= 0 ||
        st.st_size > (off_t) (MAX_SHM_SIZE+SHM_MARKER_SIZE) ||
        PA_ALIGN((size_t) st.st_size) != (size_t) st.st_size) {
        pa_log("Invalid shared memory segment size");
        goto fail;
    }

    m->size = (size_t) st.st_size;

    if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), PROT_READ, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
        pa_log("mmap() failed: %s", pa_cstrerror(errno));
        goto fail;
    }

    m->do_unlink = FALSE;
    m->shared = TRUE;

    pa_assert_se(pa_close(fd) == 0);

    return 0;

fail:
    if (fd >= 0)
        pa_close(fd);

    return -1;
}
コード例 #16
0
ファイル: flist.c プロジェクト: KimT/pulseaudio_kt
pa_flist *pa_flist_new(unsigned size) {
    pa_flist *l;

    if (!size)
        size = FLIST_SIZE;

    pa_assert(pa_is_power_of_two(size));

    l = pa_xmalloc0(PA_ALIGN(sizeof(pa_flist)) + (sizeof(pa_atomic_ptr_t) * size));

    l->size = size;

    pa_atomic_store(&l->read_idx, 0);
    pa_atomic_store(&l->write_idx, 0);
    pa_atomic_store(&l->length, 0);

    return l;
}
コード例 #17
0
ファイル: device-port.c プロジェクト: Oboyma/pulseaudio
pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *description, size_t extra) {
    pa_device_port *p;

    pa_assert(name);

    p = PA_DEVICE_PORT(pa_object_new_internal(PA_ALIGN(sizeof(pa_device_port)) + extra, pa_device_port_type_id, pa_device_port_check_type));
    p->parent.free = device_port_free;

    p->name = pa_xstrdup(name);
    p->description = pa_xstrdup(description);
    p->core = c;
    p->priority = 0;
    p->available = PA_PORT_AVAILABLE_UNKNOWN;
    p->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
    p->is_input = FALSE;
    p->is_output = FALSE;
    p->latency_offset = 0;
    p->proplist = pa_proplist_new();

    return p;
}
コード例 #18
0
ファイル: shmasyncq.c プロジェクト: Elemecca/pulseaudio
static void *get_cell_data(pa_atomic_t *a) {
    return (uint8_t*) a + PA_ALIGN(sizeof(atomic_t));
}
コード例 #19
0
ファイル: shmasyncq.c プロジェクト: Elemecca/pulseaudio
static pa_atomic_t* get_cell(pa_shmasyncq *l, unsigned i) {
    pa_assert(i < l->data->n_elements);

    return (pa_atomic_t*) ((uint8*t) l->data + PA_ALIGN(sizeof(pa_shmasyncq_data)) + i * (PA_ALIGN(sizeof(pa_atomic_t)) + PA_ALIGN(element_size)))
}
コード例 #20
0
ファイル: memblock.c プロジェクト: thewb/mokoiax
/* No lock necessary */
static void* mempool_slot_data(struct mempool_slot *slot) {
    pa_assert(slot);

    return (uint8_t*) slot + PA_ALIGN(sizeof(struct mempool_slot));
}
コード例 #21
0
ファイル: shm.c プロジェクト: UlrichEckhardt/pulseaudio
static int shm_attach(pa_shm *m, pa_mem_type_t type, unsigned id, int memfd_fd, bool writable, bool for_cleanup) {
#if defined(HAVE_SHM_OPEN) || defined(HAVE_MEMFD)
    char fn[32];
    int fd = -1;
    int prot;
    struct stat st;

    pa_assert(m);

    switch (type) {
#ifdef HAVE_SHM_OPEN
    case PA_MEM_TYPE_SHARED_POSIX:
        pa_assert(memfd_fd == -1);
        segment_name(fn, sizeof(fn), id);
        if ((fd = shm_open(fn, writable ? O_RDWR : O_RDONLY, 0)) < 0) {
            if ((errno != EACCES && errno != ENOENT) || !for_cleanup)
                pa_log("shm_open() failed: %s", pa_cstrerror(errno));
            goto fail;
        }
        break;
#endif
#ifdef HAVE_MEMFD
    case PA_MEM_TYPE_SHARED_MEMFD:
        pa_assert(memfd_fd != -1);
        fd = memfd_fd;
        break;
#endif
    default:
        goto fail;
    }

    if (fstat(fd, &st) < 0) {
        pa_log("fstat() failed: %s", pa_cstrerror(errno));
        goto fail;
    }

    if (st.st_size <= 0 ||
        st.st_size > (off_t) MAX_SHM_SIZE + (off_t) shm_marker_size(type) ||
        PA_ALIGN((size_t) st.st_size) != (size_t) st.st_size) {
        pa_log("Invalid shared memory segment size");
        goto fail;
    }

    prot = writable ? PROT_READ | PROT_WRITE : PROT_READ;
    if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(st.st_size), prot, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
        pa_log("mmap() failed: %s", pa_cstrerror(errno));
        goto fail;
    }

    /* In case of attaching to memfd areas, _the caller_ maintains
     * ownership of the passed fd and has the sole responsibility
     * of closing it down.. For other types, we're the code path
     * which created the fd in the first place and we're thus the
     * ones responsible for closing it down */
    if (type != PA_MEM_TYPE_SHARED_MEMFD)
        pa_assert_se(pa_close(fd) == 0);

    m->type = type;
    m->id = id;
    m->size = (size_t) st.st_size;
    m->do_unlink = false;
    m->fd = -1;

    return 0;

fail:
    /* In case of memfds, caller maintains fd ownership */
    if (fd >= 0 && type != PA_MEM_TYPE_SHARED_MEMFD)
        pa_close(fd);

#endif /* defined(HAVE_SHM_OPEN) || defined(HAVE_MEMFD) */

    return -1;
}
コード例 #22
0
ファイル: shm.c プロジェクト: UlrichEckhardt/pulseaudio
static inline size_t shm_marker_size(pa_mem_type_t type) {
    if (type == PA_MEM_TYPE_SHARED_POSIX)
        return PA_ALIGN(sizeof(struct shm_marker));

    return 0;
}
コード例 #23
0
ファイル: memblock.c プロジェクト: DryakhlyyZlodey/pulseaudio
/* No lock necessary */
size_t pa_mempool_block_size_max(pa_mempool *p) {
    pa_assert(p);

    return p->block_size - PA_ALIGN(sizeof(pa_memblock));
}