/* Copyright (C) 2008 by Mattia Monga <mattia.monga@unimi.it> */
/* $Id$ */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

void b_insert(char*);
void b_remove(char**);


void producer(void)
{ 
  while (1){
    char* o = (char*)malloc(sizeof(char));
    printf("Ho prodotto %x\n", o);
    b_insert(o);
  }
}

void consumer(void)
{ 
  while (1){
    char* o;
    b_remove(&o);
    free(o);
    printf("Ho consumato %x\n", o);
  }
}

int main(void){

  int p, c;
  
  p = fork();
  if (p == 0) producer();
  c = fork();
  if (c == 0) consumer();
  
  waitpid(-1, NULL, 0);

  return 0;
}

#define N 10
char* buffer[N];
int count = 0;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t full = PTHREAD_COND_INITIALIZER;
pthread_cond_t empty = PTHREAD_COND_INITIALIZER;

void b_insert(char* o)
{
  pthread_mutex_lock(&lock);

  if (count == N) pthread_cond_wait(&full, &lock);
  buffer[count++] = o;
  if (count == 1) pthread_cond_signal(&empty);

  pthread_mutex_unlock(&lock);
}

/* passaggio per indirizzo per evitare di fare la return fuori dai lock */
void b_remove(char** result)
{
  pthread_mutex_lock(&lock);

  if (count == 0) pthread_cond_wait(&empty, &lock);
  *result = buffer[--count];
  if (count == N-1) pthread_cond_signal(&full);

  pthread_mutex_unlock(&lock);
}


/* Local Variables: */
/* compile-command: "make -k " */
/* End: */


