/* pqueuep.c  -- Code file for protected circular buffer */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
#include "qelem.h"
#include "queuep.h"

   typedef struct {
     void * q;
     pthread_mutex_t mutex;
     pthread_cond_t condition;
     } pqueue;

   pqueue * pqueueinit(int size){
     pqueue * fifo = (pqueue *)malloc(sizeof(pqueue));

     fifo->q = queueinit(size);
     if(pthread_mutex_init(&(fifo->mutex), NULL) != 0) {
       perror("pthread_mutex_init");
       exit(1);}
     if(pthread_cond_init(&(fifo->condition), NULL)!= 0) {
       perror("pthread_cond_init");
       exit(1);}
     return fifo;
   }

   void pput(pqueue * fifo, elemtype v) {
     pthread_mutex_lock(&(fifo->mutex));
     while (queuefull(fifo->q)) {
       pthread_cond_wait(&(fifo->condition), &(fifo->mutex));}
     put(fifo->q, v);
     pthread_cond_signal(&(fifo->condition));
     pthread_mutex_unlock(&(fifo->mutex));
   }

   elemtype pget(pqueue * fifo) {
     elemtype t;

     pthread_mutex_lock(&(fifo->mutex));
     while (queueempty(fifo->q)) {
       pthread_cond_wait(&(fifo->condition), &(fifo->mutex));}
     t = get(fifo->q);
     pthread_cond_signal(&(fifo->condition));
     pthread_mutex_unlock(&(fifo->mutex));
     return t;
   }

   int pqueueempty(pqueue * fifo) {
     int t;

     pthread_mutex_lock(&(fifo->mutex));
     t = queueempty(fifo->q);
     pthread_mutex_unlock(&(fifo->mutex));
     return t;
   }

   int pqueuefull(pqueue * fifo) {
     int t;

     pthread_mutex_lock(&(fifo->mutex));
     t = queuefull(&(fifo->q));
     pthread_mutex_unlock(&(fifo->mutex));
     return t;
   }

