- 互斥锁:链表用在多线程中保证顺序,多个线程会操作同一个链表,互斥锁保证多线程操作的安全,互斥锁分情况使用,链表并不一定需要互斥锁。
typedef struct SDL_mutex {
pthread_mutex_t id;
} SDL_mutex;
typedef struct SDL_cond {
pthread_cond_t id;
} SDL_cond;
SDL_mutex *SDL_CreateMutex(void)
{
SDL_mutex *mutex;
mutex = (SDL_mutex *) mallocz(sizeof(SDL_mutex));
if (!mutex)
return NULL;
if (pthread_mutex_init(&mutex->id, NULL) != 0) {
free(mutex);
return NULL;
}
return mutex;
}
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
pthread_mutex_destroy(&mutex->id);
free(mutex);
}
}
void SDL_DestroyMutexP(SDL_mutex **mutex)
{
if (mutex) {
SDL_DestroyMutex(*mutex);
*mutex = NULL;
}
}
int SDL_LockMutex(SDL_mutex *mutex)
{
assert(mutex);
if (!mutex)
return -1;
return pthread_mutex_lock(&mutex->id);
}
int SDL_UnlockMutex(SDL_mutex *mutex)
{
assert(mutex);
if (!mutex)
return -1;
return pthread_mutex_unlock(&mutex->id);
}
SDL_cond *SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *) mallocz(sizeof(SDL_cond));
if (!cond)
return NULL;
if (pthread_cond_init(&cond->id, NULL) != 0) {
free(cond);
return NULL;
}
return cond;
}
void SDL_DestroyCond(SDL_cond *cond)
{
if (cond) {
pthread_cond_destroy(&cond->id);
free(cond);
}
}
void SDL_DestroyCondP(SDL_cond **cond)
{
if (cond) {
SDL_DestroyCond(*cond);
*cond = NULL;
}
}
int SDL_CondSignal(SDL_cond *cond)
{
assert(cond);
if (!cond)
return -1;
return pthread_cond_signal(&cond->id);
}
typedef struct Queue{
node *phead, *first_node, *last_node;
int count;
SDL_mutex *mutex;
SDL_mutex *ex_mutex;
SDL_cond *cond;
}queue;
typedef struct queue_node {
struct queue_node* prev;
struct queue_node* next;
void *para;
} node;
/**
双向链表 创建一个节点
@param para 要保存到链表的内容
@return 返回创建的这个节点
*/
static node* create_node(void *para)
{
node *pnode = NULL;
pnode = (node *) malloc(sizeof(node));
if (pnode)
{
pnode->prev = pnode->next = pnode;
pnode->para = para;
}
return pnode;
}
/**
创建链表的phead
@param q 链表
@return success return 0, fail return -1
*/
int create_queue(queue *q)
{
q->phead = create_node(NULL);
if (!q->phead)
return -1;
return 0;
}
/**
初始化一个链表
@param q 链表
@return 链表的头
*/
static int queue_init(queue *q)
{
memset(q, 0, sizeof(queue));
q->phead = NULL;
q->last_node = NULL;
q->first_node = NULL;
q->count = 0;
q->mutex = SDL_CreateMutex();
if (!q->mutex)
{
av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
q->ex_mutex = SDL_CreateMutex();
if (!q->ex_mutex)
{
av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
q->cond = SDL_CreateCond();
if (!q->cond)
{
av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
return create_queue(q);
}
/**
判断链表是否为空
@param q 链表
@return 空:return 1,不是空:return 0
*/
int queue_is_empty(queue *q)
{
return q->count == 0;
}
/**
获取链表长度
@param q 链表
@return 链表中元素的个数
*/
int queue_size(queue *q)
{
return q->count;
}
/**
根据index获取链表的节点
@param q 链表
@param index 链表元素下标
@return 该下标的链表元素节点。
*/
static node* get_node(queue *q,int index)
{
if (index < 0 || index >= q->count)
return NULL;
if (index <= (q->count / 2))
{
int i = 0;
node *pnode = q->phead->next;
while ((i++) < index)
pnode = pnode->next;
return pnode;
}
int j = 0;
int rindex = q->count - index - 1;
node *rnode = q->phead->prev;
while ((j++) < rindex)
rnode = rnode->prev;
return rnode;
}
/**
根据index获取改链表节点里面的存储内容
@param q 链表
@param index 链表节点下标
@return 该下标元素节点中存储的内容
*/
void* queue_get(queue *q,int index)
{
SDL_LockMutex(q->mutex);
node *pindex = get_node(q,index);
if (!pindex)
{
SDL_UnlockMutex(q->mutex);
return NULL;
}
SDL_UnlockMutex(q->mutex);
return pindex->para;
}
/**
获取该链表第一个节点存储的内容
@param q 链表
@return 该链表的某个节点内容
*/
void* queue_get_first(queue *q)
{
return queue_get(q,0);
}
/**
获取该链表最后一个节点存储的内容
@param q 链表
@return 该链表的某个节点内容
*/
void* queue_get_last(queue *q)
{
return queue_get(q,q->count - 1);
}
/**
存储一个元素到链表
@param q 要存储到的链表
@param para 要存储的内容
@return success return 0 ,fail return -1
*/
int queue_append_last(queue *q,void *para)
{
SDL_LockMutex(q->mutex);
node *pnode = create_node(para);
if (!pnode)
{
SDL_UnlockMutex(q->mutex);
return -1;
}
pnode->next = q->phead;
pnode->prev = q->phead->prev;
q->phead->prev->next = pnode;
q->phead->prev = pnode;
q->last_node = pnode;
q->count++;
SDL_UnlockMutex(q->mutex);
return 0;
}
/**
根据index 删除链表的元素节点
@param q 链表
@param index 要删除的节点下标
@return success return 0 ,fail return -1
*/
int queue_delete(queue *q,int index)
{
SDL_LockMutex(q->mutex);
node *pindex = get_node(q,index);
if (!pindex)
{
SDL_UnlockMutex(q->mutex);
return -1;
}
pindex->next->prev = pindex->prev;
pindex->prev->next = pindex->next;
free(pindex);
q->count--;
SDL_UnlockMutex(q->mutex);
return 0;
}
/**
删除该链表第一个节点
@param q 链表
@return success return 0 ,fail return -1
*/
int queue_delete_first(queue *q)
{
return queue_delete(q,0);
}
/**
删除该链表最后一个节点
@param q 链表
@return success return 0 ,fail return -1
*/
int queue_delete_last(queue *q)
{
return queue_delete(q, q->count - 1);
}
/**
销毁链表
@param q 链表
@return success return 0 ,fail return -1
*/
int destroy_queue(queue *q)
{
SDL_LockMutex(q->mutex);
if (!q->phead)
{
SDL_UnlockMutex(q->mutex);
return -1;
}
node *pnode = q->phead->next;
node *ptmp = NULL;
while (pnode != q->phead)
{
ptmp = pnode;
pnode = pnode->next;
free(ptmp);
}
free(q->phead);
q->phead = NULL;
q->last_node = NULL;
q->first_node = NULL;
q->count = 0;
SDL_UnlockMutex(q->mutex);
SDL_DestroyMutex(q->mutex);
SDL_DestroyCond(q->cond);
return 0;
}