libevent中queue相关宏主要参考linux内核头文件<sys/queue.h>作了稍许的修改
Linux自带头文件的队列链表相关宏使用可以在man手册中查到(man 3 queue)

libevent中的queue.h头文件主要包含了5种队列数据结构,下面将以代码形式列出如何使用这些宏

1、singly-linked lists

#include <stdio.h>
#include <stdlib.h> /*for malloc free exit*/
#include "queue.h"

/*list struct*/
struct slist_entry_t
{
    int data;
    SLIST_ENTRY(slist_entry_t) entry;
};

SLIST_HEAD(slist_t,slist_entry_t) slistHead;
/*
    struct slist_t slistHead;
*/

#if 0
/*SLIST_ENTRY 和 SLIST_HEAD宏的展开*/
struct slist_entry_t
{
    int data;
    struct
    {
        struct slist_entry_t *sle_next;
    } entry;
}

struct slist_t
{
    struct slist_entry_t *slh_first;
}

#endif

#define LIST_NUM 10

int main(int argc, char **argv)
{
    int count = 0;
    /*slist*/
    showline();
    struct slist_entry_t *pstEntry = NULL;
    SLIST_INIT(&slistHead);
    
    /*insert from head, insert LIST_NUM items*/
    for(count =0 ;count< LIST_NUM;count++)
    {
        pstEntry = (struct slist_entry_t *)malloc(sizeof(struct slist_entry_t));
        if(!pstEntry)
        {
            fprintf(stderr,"error malloc \n");
            exit(-1);
        }
        pstEntry->data = count;
        SLIST_INSERT_HEAD(&slistHead,pstEntry,entry);
    }
    /*test insert data*/
    if(SLIST_EMPTY(&slistHead))
    {
        fprintf(stderr,"error, slist empty\n");
        exit(-1);
    }
    SLIST_FOREACH(pstEntry,&slistHead,entry)
    {
        printf("slist test:%d\n", pstEntry->data);
    }
    
    #if 0
    /*for each with while and SLIST_NEXT*/
    pstEntry = slistHead.slh_first;
    while(pstEntry)
    {
        printf("slist test:%d\n", pstEntry->data);
        pstEntry = SLIST_NEXT(pstEntry,entry);
    };
    #endif
    return 0;
}

2、lists


#include <stdio.h>
#include <stdlib.h> /*for malloc free exit*/
#include "queue.h"

/*list struct*/
struct list_entry_t
{
    int data;
    LIST_ENTRY(list_entry_t) entry;
};

LIST_HEAD(list_t,list_entry_t) listHead;
/*
    struct list_t listHead;
*/

#if 0
/*list_ENTRY 和 list_HEAD宏的展开*/
struct list_entry_t
{
    int data;
    struct
    {
        struct list_entry_t *le_next;
        struct list_entry_t **le_prev;
    } entry;
}

struct list_t
{
    struct list_entry_t *lh_first;
}

#endif
#define LIST_NUM 10

int main(int argc, char **argv)
{
    int count = 0;
    
    struct list_entry_t *pstEntry = NULL;
    struct list_entry_t *pstTemp = NULL;
    LIST_INIT(&listHead);
    
    /*insert from head, insert LIST_NUM items*/
    for(count =0 ;count< LIST_NUM;count++)
    {
        pstEntry = (struct list_entry_t *)malloc(sizeof(struct list_entry_t));
        if(!pstEntry)
        {
            fprintf(stderr,"error malloc \n");
            exit(-1);
        }
        pstEntry->data = count;
        LIST_INSERT_HEAD(&listHead,pstEntry,entry);
    }
    /*insert after element*/
    pstEntry = (struct list_entry_t *)malloc(sizeof(struct list_entry_t));
    if(!pstEntry)
    {
        fprintf(stderr,"error malloc \n");
        exit(-1);
    }
    pstEntry->data = 11;
    LIST_INSERT_AFTER(listHead.lh_first,pstEntry,entry);
    
    /*insert before element*/
    pstTemp = (struct list_entry_t *)malloc(sizeof(struct list_entry_t));
    if(!pstTemp)
    {
        fprintf(stderr,"error malloc \n");
        exit(-1);
    }
    pstTemp->data = 12;
    
    LIST_INSERT_BEFORE(pstEntry,pstTemp,entry);
    
    /*test insert data*/
    if(LIST_EMPTY(&listHead))
    {
        fprintf(stderr,"error, list empty\n");
        exit(-1);
    }
    
    /*remove test*/
    LIST_FOREACH(pstEntry,&listHead,entry)
    {
        printf("remove test:%d\n", pstEntry->data);
        LIST_REMOVE(pstEntry,entry);
        free(pstEntry);
        break;
    }
    
    /*data check*/
    LIST_FOREACH(pstEntry,&listHead,entry)
    {
        printf("list test:%d\n", pstEntry->data);
        LIST_REMOVE(pstEntry,entry);
        free(pstEntry);
    }
    
    return 0;
}

3、simple queues

#include <stdio.h>
#include <stdlib.h> /*for malloc free exit*/
#include "queue.h"

/*simple queue struct*/
struct simple_queue_entry_t
{
    int data;
    SIMPLEQ_ENTRY(simple_queue_entry_t) entry;
};

SIMPLEQ_HEAD(simple_queue_t,simple_queue_entry_t) queueHead;
/*
    struct simple_queue_t queueHead;
*/

#if 0
/*SIMPLEQ_ENTRY 和 SIMPLEQ_HEAD宏展开*/
struct simple_queue_entry_t
{
    int data;
    struct
    {
        struct simple_queue_entry_t *sqe_next;
    } entry;
}

struct simple_queue_t
{
    struct simple_queue_entry_t *sqh_first;
    struct simple_queue_entry_t **sqh_last;
}
#endif
#define SIMPLEQ_ENTRY_NUM 10

int main(int argc, char **argv)
{
    int count = 0;
    
    struct simple_queue_entry_t *pstEntry = NULL;
    struct simple_queue_entry_t *pstTemp = NULL;
    SIMPLEQ_INIT(&queueHead);
    
    /*insert from head, insert SIMPLEQ_ENTRY_NUM items*/
    for(count =0 ;count< SIMPLEQ_ENTRY_NUM;count++)
    {
        pstEntry = (struct simple_queue_entry_t *)malloc(sizeof(struct simple_queue_entry_t));
        if(!pstEntry)
        {
            fprintf(stderr,"error malloc \n");
            exit(-1);
        }
        pstEntry->data = count;
        SIMPLEQ_INSERT_HEAD(&queueHead,pstEntry,entry);
    }
    /*insert after element*/
    pstEntry = (struct simple_queue_entry_t *)malloc(sizeof(struct simple_queue_entry_t));
    if(!pstEntry)
    {
        fprintf(stderr,"error malloc \n");
        exit(-1);
    }
    pstEntry->data = 11;
    
    SIMPLEQ_INSERT_AFTER(&queueHead,queueHead.sqh_first,pstEntry,entry);
    
    /*insert tail*/
    pstTemp = (struct simple_queue_entry_t *)malloc(sizeof(struct simple_queue_entry_t));
    if(!pstTemp)
    {
        fprintf(stderr,"error malloc \n");
        exit(-1);
    }
    pstTemp->data = 12;
    
    SIMPLEQ_INSERT_TAIL(&queueHead,pstTemp,entry);
    
    /*test insert data*/
    if(SIMPLEQ_EMPTY(&queueHead))
    {
        fprintf(stderr,"error, queue empty\n");
        exit(-1);
    }
    
    /*remove from head*/
    SIMPLEQ_REMOVE_HEAD(&queueHead,queueHead.sqh_first,entry);
    
    /*data check*/
    SIMPLEQ_FOREACH(pstEntry,&queueHead,entry)
    {
        printf("queue test:%d\n", pstEntry->data);
        SIMPLEQ_REMOVE_HEAD(&queueHead,pstEntry,entry);
        free(pstEntry);
    }
    
    return 0;
}

4、tail queues

#include <stdio.h>
#include <stdlib.h> /*for malloc free exit*/
#include "queue.h"

/*tail queue struct*/
struct tail_queue_entry_t
{
    int data;
    TAILQ_ENTRY(tail_queue_entry_t) entry;
};

TAILQ_HEAD(tail_queue_t,tail_queue_entry_t) queueHead;
/*
    struct tail_queue_t queueHead;
*/

#if 0
/*TAILQ_ENTRY 和 TAILQ_HEAD宏展开*/
struct tail_queue_entry_t
{
    int data;
    struct
    {
        struct tail_queue_entry_t *tqe_next;
        struct tail_queue_entry_t **tqe_prev;
    } entry;
}

struct tail_queue_t
{
    struct tail_queue_entry_t *tqh_first;
    struct tail_queue_entry_t **tqh_last;
}
#endif
#define TAILQ_ENTRY_NUM 10

int main(int argc, char **argv)
{
    int count = 0;
    
    struct tail_queue_entry_t *pstEntry = NULL;
    struct tail_queue_entry_t *pstTemp = NULL;
    TAILQ_INIT(&queueHead);
    
    /*insert from head, insert TAILQ_ENTRY_NUM items*/
    for(count =0 ;count< TAILQ_ENTRY_NUM;count++)
    {
        pstEntry = (struct tail_queue_entry_t *)malloc(sizeof(struct tail_queue_entry_t));
        if(!pstEntry)
        {
            fprintf(stderr,"error malloc \n");
            exit(-1);
        }
        pstEntry->data = count;
        TAILQ_INSERT_HEAD(&queueHead,pstEntry,entry);
    }
    /*insert after element*/
    pstEntry = (struct tail_queue_entry_t *)malloc(sizeof(struct tail_queue_entry_t));
    if(!pstEntry)
    {
        fprintf(stderr,"error malloc \n");
        exit(-1);
    }
    pstEntry->data = 11;
    
    TAILQ_INSERT_AFTER(&queueHead,queueHead.tqh_first,pstEntry,entry);
    
    /*insert tail*/
    pstEntry = (struct tail_queue_entry_t *)malloc(sizeof(struct tail_queue_entry_t));
    if(!pstEntry)
    {
        fprintf(stderr,"error malloc \n");
        exit(-1);
    }
    pstEntry->data = 12;
    
    TAILQ_INSERT_TAIL(&queueHead,pstEntry,entry);
    
    /*test insert data*/
    if(TAILQ_EMPTY(&queueHead))
    {
        fprintf(stderr,"error, queue empty\n");
        exit(-1);
    }
    
    /*remove from head*/
    pstEntry = queueHead.tqh_first;
    TAILQ_REMOVE(&queueHead,queueHead.tqh_first,entry);
    free(pstEntry);
    
    /*data check*/
    for(pstEntry = TAILQ_FIRST(&queueHead); pstEntry != NULL; pstEntry = pstTemp)
    {
        pstTemp = TAILQ_NEXT(pstEntry,entry);
        printf("queue test:%d\n", pstEntry->data);
        TAILQ_REMOVE(&queueHead,pstEntry,entry);
        free(pstEntry);
    }
    
    /*test delete data*/
    if(TAILQ_EMPTY(&queueHead))
    {
        fprintf(stdout,"success, queue is empty!\n");
        exit(0);
    }
    
    return 0;
}

5、circular queues

    #include <stdio.h>
#include <stdlib.h> /*for malloc free exit*/
#include "queue.h"

/*circularqueue queue struct*/
struct circularqueue_queue_entry_t
{
    int data;
    CIRCLEQ_ENTRY(circularqueue_queue_entry_t) entry;
};

CIRCLEQ_HEAD(circularqueue_queue_t,circularqueue_queue_entry_t) queueHead;
/*
    struct circularqueue_queue_t queueHead;
*/

#if 0
/*CIRCLEQ_ENTRY 和 CIRCLEQ_HEAD宏展开*/
struct circularqueue_queue_entry_t
{
    int data;
    struct
    {
        struct circularqueue_queue_entry_t *cqe_next;
        struct circularqueue_queue_entry_t *cqe_prev;
    } entry;
}

struct circularqueue_queue_t
{
    struct circularqueue_queue_entry_t *cqh_first;
    struct circularqueue_queue_entry_t *cqh_last;
}
#endif
#define CIRCLEQ_ENTRY_NUM 10

int main(int argc, char **argv)
{
    int count = 0;
    
    struct circularqueue_queue_entry_t *pstEntry = NULL;
    struct circularqueue_queue_entry_t *pstTemp = NULL;
    CIRCLEQ_INIT(&queueHead);
    
    /*insert from head, insert CIRCLEQ_ENTRY_NUM items*/
    for(count =0 ;count< CIRCLEQ_ENTRY_NUM;count++)
    {
        pstEntry = (struct circularqueue_queue_entry_t *)malloc(sizeof(struct circularqueue_queue_entry_t));
        if(!pstEntry)
        {
            fprintf(stderr,"error malloc \n");
            exit(-1);
        }
        pstEntry->data = count;
        CIRCLEQ_INSERT_HEAD(&queueHead,pstEntry,entry);
    }
    /*insert after element*/
    pstEntry = (struct circularqueue_queue_entry_t *)malloc(sizeof(struct circularqueue_queue_entry_t));
    if(!pstEntry)
    {
        fprintf(stderr,"error malloc \n");
        exit(-1);
    }
    pstEntry->data = 11;
    
    pstTemp = CIRCLEQ_FIRST(&queueHead);
    CIRCLEQ_INSERT_AFTER(&queueHead,pstTemp,pstEntry,entry);
    
    /*insert circularqueue*/
    pstEntry = (struct circularqueue_queue_entry_t *)malloc(sizeof(struct circularqueue_queue_entry_t));
    if(!pstEntry)
    {
        fprintf(stderr,"error malloc \n");
        exit(-1);
    }
    pstEntry->data = 12;
    
    CIRCLEQ_INSERT_TAIL(&queueHead,pstEntry,entry);
    
    /*test insert data*/
    if(CIRCLEQ_EMPTY(&queueHead))
    {
        fprintf(stderr,"error, queue empty\n");
        exit(-1);
    }
    
    /*remove from head*/
    pstEntry = CIRCLEQ_FIRST(&queueHead);
    CIRCLEQ_REMOVE(&queueHead,pstEntry,entry);
    free(pstEntry);
    
    /*data check*/
    for(pstEntry = CIRCLEQ_FIRST(&queueHead);!CIRCLEQ_EMPTY(&queueHead); pstEntry = pstTemp)
    {
        pstTemp = CIRCLEQ_NEXT(pstEntry,entry);
        printf("queue test:%d\n", pstEntry->data);
        CIRCLEQ_REMOVE(&queueHead,pstEntry,entry);
        free(pstEntry);
    }
    
    /*test delete data*/
    if(CIRCLEQ_EMPTY(&queueHead))
    {
        fprintf(stdout,"success, queue is empty!\n");
        exit(0);
    }
    
    return 0;
}

【源码】
singlelist.c
list.c
queue.h
tailqueue.c
circularqueue.c
queue.h