Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenSL ES full duplex restored #196

Merged
merged 9 commits into from
Nov 18, 2016
118 changes: 118 additions & 0 deletions src/cubeb_array_queue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/

#ifndef CUBEB_ARRAY_QUEUE_H
#define CUBEB_ARRAY_QUEUE_H

#include <assert.h>
#include <pthread.h>
#include <unistd.h>

#if defined(__cplusplus)
extern "C" {
#endif

typedef struct
{
void ** buf;
size_t num;
size_t writePos;
size_t readPos;
pthread_mutex_t mutex;
pthread_cond_t empty_convar;
} array_queue;

array_queue * array_queue_create(size_t num)
{
assert(num != 0);
array_queue * new_queue = (array_queue*)calloc(1, sizeof(array_queue));
new_queue->buf = (void **)calloc(1, sizeof(void *) * num);
new_queue->readPos = 0;
new_queue->writePos = 0;
new_queue->num = num;

pthread_mutex_init(&new_queue->mutex, NULL);
pthread_cond_init(&new_queue->empty_convar, NULL);

return new_queue;
}

void array_queue_destroy(array_queue * aq)
{
assert(aq);

free(aq->buf);
pthread_mutex_destroy(&aq->mutex);
pthread_cond_destroy(&aq->empty_convar);
free(aq);
}

int array_queue_push(array_queue * aq, void * item)
{
assert(item);

pthread_mutex_lock(&aq->mutex);
int ret = -1;
if(aq->buf[aq->writePos % aq->num] == NULL)
{
aq->buf[aq->writePos % aq->num] = item;
aq->writePos = (aq->writePos + 1) % aq->num;
ret = 0;
}
// else queue is full
pthread_cond_signal(&aq->empty_convar);
pthread_mutex_unlock(&aq->mutex);
return ret;
}

void* array_queue_pop(array_queue * aq)
{
pthread_mutex_lock(&aq->mutex);
void * value = aq->buf[aq->readPos % aq->num];
if(value)
{
aq->buf[aq->readPos % aq->num] = NULL;
aq->readPos = (aq->readPos + 1) % aq->num;
}
pthread_mutex_unlock(&aq->mutex);
return value;
}

void* array_queue_wait_pop(array_queue * aq)
{
pthread_mutex_lock(&aq->mutex);
while (aq->readPos == aq->writePos) {
// Wait here if queue is empty
pthread_cond_wait(&aq->empty_convar, &aq->mutex);
}
void * value = aq->buf[aq->readPos % aq->num];
// Since it has been waiting it is expected to
// return a non NULL value.
assert(value);
aq->buf[aq->readPos % aq->num] = NULL;
aq->readPos = (aq->readPos + 1) % aq->num;
pthread_mutex_unlock(&aq->mutex);
return value;
}

size_t array_queue_get_size(array_queue * aq)
{
pthread_mutex_lock(&aq->mutex);
ssize_t r = aq->writePos - aq->readPos;
if (r < 0) {
r = aq->num + r;
assert(r >= 0);
}
pthread_mutex_unlock(&aq->mutex);
return (size_t)r;
}

#if defined(__cplusplus)
}
#endif

#endif //CUBE_ARRAY_QUEUE_H
Loading