

#include <assert.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>

#include "http_request_queue.h"
#include "message.h"

struct s_HttpRequestQueue
{
    lstTlist *queue;
    pthread_mutex_t queueMutex;
    sem_t   queueSemaphore;
};

HttpRequestQueue *
http_request_queue_new()
{
    HttpRequestQueue *resp = malloc (sizeof (HttpRequestQueue));

    sem_init (&resp->queueSemaphore, 0, 0);
    pthread_mutex_init (&resp->queueMutex, NULL);

    resp->queue = lstFlist_create (NULL);

    return (resp);
}

void
http_request_queue_destroy (void *ptr)
{
    HttpRequestQueue *resp = (HttpRequestQueue *) ptr;

    sem_destroy (&resp->queueSemaphore);
    pthread_mutex_destroy (&resp->queueMutex);

    lstFlist_free (resp->queue);

    free (resp);
}

HttpRequest *
http_request_queue_getRequest (HttpRequestQueue *resp)
{
    HttpRequest *request;

    /* this will block until it is 1 */
    sem_wait (&resp->queueSemaphore);

    pthread_mutex_lock (&resp->queueMutex);

    assert (lstFlist_size (resp->queue) > 0);

    lstFlist_remove (resp->queue, lstFlist_head (resp->queue), (void **) &request);

    pthread_mutex_unlock (&resp->queueMutex);

    return (request);
}

void
http_request_queue_addRequest (HttpRequestQueue *resp, HttpRequest *request)
{
    pthread_mutex_lock (&resp->queueMutex);

    lstFlist_add_next (resp->queue, lstFlist_tail (resp->queue), request);

    pthread_mutex_unlock (&resp->queueMutex);

    /* this will increment the semaphore to 1 */
    sem_post (&resp->queueSemaphore);
}

