#include "ipc_cq.h"
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

struct cq *g_cq;

struct cq *CQ_Create(void) {
    struct cq *q = (struct cq*)malloc(sizeof(*q));
    if (!q) return NULL;
    q->head = q->tail = NULL;
    pthread_mutex_init(&q->lock, NULL);
    return q;
}

void CQ_Destroy(struct cq *q) {
    while (q->head) {
        struct cq_item *tmp = q->head;
        q->head = tmp->next;
        free(tmp->resp->data); // 如果 resp 有 data
        free(tmp->resp);
        free(tmp);
    }
    pthread_mutex_destroy(&q->lock);
    free(q);
}

/* 推入响应 */
void CQ_Push(struct cq *q, struct zvfs_resp *resp) {
    struct cq_item *item = (struct cq_item *)malloc(sizeof(*item));
    item->resp = resp;
    item->next = NULL;

    pthread_mutex_lock(&q->lock);
    if (q->tail) {
        q->tail->next = item;
        q->tail = item;
    } else {
        q->head = q->tail = item;
    }
    pthread_mutex_unlock(&q->lock);
}

/* 弹出响应 */
struct zvfs_resp *CQ_Pop(struct cq *q) {
    pthread_mutex_lock(&q->lock);
    struct cq_item *item = q->head;
    if (!item) {
        pthread_mutex_unlock(&q->lock);
        return NULL;
    }
    q->head = item->next;
    if (!q->head) q->tail = NULL;
    pthread_mutex_unlock(&q->lock);

    struct zvfs_resp *resp = item->resp;
    free(item);
    return resp;
}