把一些公共的基础接口做个简单的整理,夯实基础。
链表创建:
typedef struct
{
Uint16 maxElems;//队列成员数量
Uint16 flags;//标志,暂未使用
Uint32 *pQueue;//que队列可传入,queList无效
Uint32 reserved[4];
}queCreate;
//这个头定义有点特殊,结构体成员的类型是定义结构体本身
typedef struct listHead
{
struct listHead *next;
struct listHead *prev;
}listHead;
typedef struct
{
Uint32 len;
Uint32 count;
listHead queHead;
pthread_mutex_t lock;//互斥锁,防止多个线程同时访问该资源
pthread_cond_t condRd;//线程读等待条件
pthread_cond_t condWr;
}queListObj;
/*链表初始化*/
static inline void listHeadInit(listHead *list)
{
list->next = list;
list->prev = list;
}
/******************************
*pCreate 创建参数
*phQue 返回句柄 实际上就是申请结构体的指针
********************************/
Int32 queListCreate(queCreate *pCreate,queHandle *phQue)
{
queListObj *pQueObj = NULL;
assetNotNull(pCreate);
assetNotNull(phQue);
if(pCreate->maxElems == 0)
{
error("maxElems is zero!\n");
return EFAIL;
}
pQueObj = memAlloc(sizeof(*pQueObj));
if(isNull(pQueObj))
{
error("queue obj alloc fail!\n");
return EFAIL;
}
clear(pQueObj);
pQueObj->len = pCreate->maxElems;
listHeadInit(&pQueObj->queHead);
pthread_mutex_init(&pQueObj->lock,NULL);
pthread_cond_init(&pQueObj->condRd,NULL);
pthread_cond_init(&pQueObj->condWr,NULL);
*phQue = (queHandle)pQueObj;
return OK;
}
以上为链表初始化的创建,接下来是相应的put和get函数:
/*head的next指向下一个元素,head的prev指向队尾*/
static void listAddTail(listHead *newList,listHead *head)
{
listHead headPrev = head->prev;
head->prev = newLis;
newList->next = head;
newList->prev = headPrev;
headPrev->next = newList;
}
Int32 queListPut(queHandle hQue,listHead pQueElem,Uint32 timeout)
{
Int32 status = OK;
queListObj *pQueObj = (queListObj *)hQue;
struct timespec waitTime;
timeVal timeVal;
assertNotNull(hQue);
assertNotNull(pQueElem);
pthread_mutex_lock(&pQueObj->lock);//互斥锁,资源保护
do
{
if(pQueObj->count < pQueObj->len)//计数小于最大个数,表明还可以继续写入
{
if(0 == pQueObj->count)
{
pthread_cond_signal(&pQueObj->condRd);//告知傻等的读取队列,有数据写入了,可以去读了!
}
listAddTail(pQueElem,&pQueObj->queHead);
pQueObj->count++;
break;
}
else
{
//队列中没有空间可以写了,分以下三种方式来处理
//1、直接返回错误;2、一直傻等;3、等待指定时间
if(timeout == TIMEOUT_NONE)
{
status = EFAIL;
break;
}
if(timeout == TIMEOUT_FOREVER)
{
status = pthread_cond_wait(&pQueObj->condWr,&pQueObj->lock);
if(0 != status)
{
error("pthread_cond_wait failed, ret:%d\n",status);
status = EFAIL;
break;
}
}
else
{
//等待指定时间,稍复杂,需时间系统配合
waitTime.tv_sec = (Int32L)timeout/1000;
waitTime.tv_nsec = ((Int32L)timeout%1000)*1000000;
getTimeOfDay(&timeVal);
waitTime.tv_sec += timeVal.tvSec;
waitTime.tv_nsec += timeVal.tvUsec * 1000;
if()
{
waitTime.tv_sec += 1;
waitTime.tv_nsec %= 1000000000;
}
status = pthread_cond_timedwait(&pQueObj->condWr,&pQueObj->lock,&waitTime);
if(ETIMEDOUT == status)
{
status = eTIEMDOUT;
break;
}
else if(OK != status)
{
error("");
status = EFAIL;
break;
}
}
}
}while(1);
pthread_mutex_unlock(&pQueObj->lock);
return status;
}
以下为读出函数实现:
/*判断链表是否为空*/
static inline int listEmpty(const listHead *head)
{
return head->next == head;
}
/*从链表中删除成员*/
static void listDel(listHead *entry)
{
listHead *prev = entry->prev;
listHead *next = entry->next;
next->prev = prev;
prev->next = next;
entry->prev = NULL;
entry->next = NULL;
}
Int32 queListGet(queHandle hQue,listHead **ppQueElem,Uint32 timeout)
{
Int32 status = OK;
queListObj *pQueObj = (queListObj *)hQue;
struct timespec waitTime;
timeVal timeVal;
pthread_mutex_lock(&pQueObj->lock);
do
{
if(!listEmpty(&pQueObj->queHead))
{
//有数据可读
*ppQueElem = pQueObj->queHead.next;
listDel(*ppQueElem);
if(pQueObj->count == pQueObj->len)
{
//写满数据了,写就一直等在那,现在可以告知它可以写了
pthread_cond_signal(&pQueObj->condWr);
}
pQueObj->count--;
break;
}
else
{
//无数据可读
//同样分三种情况来处理,参照上面的写流程
if(timeout == TIMEOUT_NONE)
{
status = EFAIL;
break;
}
if(timeout == TIMEOUT_FOREVER)
{
status = pthread_cond_wait(&pQueObj->condRd,&pQueObj->lock);
if(0 != status)
{
error("");
status = EFAIL;
break;
}
}
else
{
waitTime.tv_sec = (Int32L)timeout/1000;
waitTime.tv_nsec = ((Int32L)timeout%1000)*1000000;
getTimeOfDay(&timeVal);
waitTime.tv_sec += timeVal.tvSec;
waitTime.tv_nsec += timeVal.tvUsec * 1000;
if(waitTime.tv_nsec >= 1000000000)
{
waitTime.tv_sec += 1;
waitTime.tv_nsec %= 1000000000;
}
status = pthread_cond_timedwait(&pQueObj->condRd,&pQueObj->lock,&waitTime);
if(ETIMEDOUT == status)
{
status = eTIEMDOUT;
break;
}
else if(OK != status)
{
error("");
status = EFAIL;
break;
}
}
}
}while(1);
pthread_mutex_unlock(&pQueObj->lock);
return status;
}