Per preparami ad un esame di Programmazione concorrente devo risolvere un problema dei produttori consumatori definendo un oggetto buffer_t che mi rappresenta il buffer contenente D indice inserimento buffer circolare, T indice estrazione elementi buffer circolare e un buffer circolare che contiene dei messaggi del tipo msg_t *.
Io ho scritto il seguente codice:

codice:
GestioneBuffer.c

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<string.h>
#define BUFFERERROR (msg_t *) NULL;
typedef char* stringa;
typedef struct msg {
    void* content;
// generico contenuto del messaggio
    struct msg * (*msg_init_string)(void*);
// creazione msg
    void (*msg_destroy_string)(struct msg *);
// deallocazione msg
    struct msg * (*msg_copy_string)(struct msg *); // creazione/copia msg
} msg_t;

typedef struct buffer{

    int K; //numero messaggi
    int N; //capacita bffer circolare
    int D;
    int T;
    msg_t **buffer_circolare;
    pthread_mutex_t mutex;
    pthread_cond_t non_pieno;
    pthread_cond_t non_vuoto;



}buffer_t;




void msg_destroy_string(msg_t* msg) {
    free(msg->content); // free copia privata
    free(msg);
// free struct
}

msg_t* msg_copy_string(msg_t* msg) {
    return msg->msg_init_string( msg->content );
}
msg_t* msg_init_string(void* content) {


//viene creata una copia "privata" della stringa
    msg_t* new_msg = (msg_t*)malloc( sizeof(msg_t) );
    char* string = (char*)content;
    char* new_content = (char*)malloc(strlen(string)+1); // +1 per \0 finale
    strcpy(new_content, string);
    new_msg->content=new_content;
    new_msg->msg_init_string=msg_init_string;
    new_msg->msg_destroy_string=msg_destroy_string;
    new_msg->msg_copy_string=msg_copy_string;
    return new_msg;
}

void buffer_destroy(buffer_t* buffer){
    free(buffer);
}

buffer_t* buffer_init(unsigned int maxsize){
    buffer_t *buffer;
    buffer = (buffer_t *)malloc(sizeof(buffer_t));
    buffer->buffer_circolare = malloc(maxsize*sizeof(msg_t));
    buffer->D=0;
    buffer->K=0;
    buffer->T=0;
    buffer->N=maxsize;
    pthread_mutex_init(&buffer->mutex,NULL);
    pthread_cond_init(&buffer->non_pieno,NULL);
    pthread_cond_init(&buffer->non_vuoto,NULL);
    return buffer;



}

msg_t* put_non_bloccante(buffer_t *buffer){

    pthread_mutex_lock(&buffer->mutex);

    if(buffer->K==buffer->N){
        printf("Il buffer è pieno e il mutex è rilasciato\n");
        pthread_mutex_unlock(&buffer->mutex);
        return NULL;

    }else{

        msg_t* msg=msg_init_string("Messaggio");
        buffer->buffer_circolare[buffer->D]=msg_copy_string(msg);
        printf("Il produttore inserisce il messaggio\n");
        buffer->D=(buffer->D+1)%buffer->N;
        buffer->K=buffer->K+1;
        pthread_cond_signal(&buffer->non_vuoto);
        pthread_mutex_unlock(&buffer->mutex);
        return msg;

    }
}



msg_t* put_bloccante(buffer_t *buffer){

        msg_t *msg = msg_init_string("Messaggio");
        pthread_mutex_lock(&buffer->mutex);

        while(buffer->K==buffer->N){
            printf("Il Produttore è in attesa che il buffer sia vuoto\n");
            pthread_cond_wait(&buffer->non_pieno,&buffer->mutex);


        }

        buffer->buffer_circolare[buffer->D]=msg_copy_string(msg);
        printf("Il produttore inserisce il messaggio\n");
        buffer->D=(buffer->D+1)%buffer->N;
        buffer->K=buffer->K+1;

        pthread_cond_signal(&buffer->non_vuoto);
        pthread_mutex_unlock(&buffer->mutex);
        return msg;

    /**}else return BUFFERERROR;*/

}

msg_t* get_bloccante(buffer_t* buffer){
    msg_t*result;
    pthread_mutex_lock(&buffer->mutex);

    while(buffer->K==0){
                printf("Il consumatore è in attesa che il buffer venga riempito\n");
                pthread_cond_wait(&buffer->non_vuoto,&buffer->mutex);


    }
    printf("Il consumatore preleva un messaggio\n");
    result=(msg_t*)malloc( sizeof(msg_t) );
    result=buffer->buffer_circolare[buffer->T];
    buffer->buffer_circolare[buffer->T]=NULL;
    buffer->T=(buffer->T+1)%buffer->N;
    buffer->K=buffer->K-1;
    pthread_cond_signal(&buffer->non_pieno);
    pthread_mutex_unlock(&buffer->mutex);
    return result;

}

msg_t* get_non_bloccante(buffer_t* buffer){
    pthread_mutex_lock(&buffer->mutex);
    if(buffer->K==0){
        printf("Il consumatore non preleva poiche buffer vuoto\n");
        pthread_mutex_unlock(&buffer->mutex);
        return NULL;

    }else{
        printf("Il consumatore preleva un messaggio\n");
        msg_t* result=(msg_t*)malloc( sizeof(msg_t) );
        result=msg_copy_string(buffer->buffer_circolare[buffer->T]);
        buffer->buffer_circolare[buffer->T]=NULL;
        buffer->T=(buffer->T+1)%buffer->N;
        buffer->K=buffer->K-1;
        pthread_cond_signal(&buffer->non_pieno);
        pthread_mutex_unlock(&buffer->mutex);
        return result;
    }
}

msg_t* dummy_produttore(buffer_t* buffer){
            msg_t *msg = msg_init_string("Messaggio");
            pthread_mutex_lock(&buffer->mutex);
            buffer->buffer_circolare[buffer->D]=msg_copy_string(msg);
            printf("Il produttore inserisce il messaggio\n");
            buffer->D=(buffer->D+1)%buffer->N;
            buffer->K=buffer->K+1;
            pthread_cond_signal(&buffer->non_vuoto);
            pthread_mutex_unlock(&buffer->mutex);
            return msg;


}

msg_t* dummy_consumatore(buffer_t* buffer){
        msg_t*result;
        pthread_mutex_lock(&buffer->mutex);
        printf("Il consumatore preleva un messaggio\n");
        result=(msg_t*)malloc( sizeof(msg_t) );
        result=buffer->buffer_circolare[buffer->T];
        buffer->buffer_circolare[buffer->T]=NULL;
        buffer->T=(buffer->T+1)%buffer->N;
        buffer->K=buffer->K-1;
        pthread_cond_signal(&buffer->non_pieno);
        pthread_mutex_unlock(&buffer->mutex);
        return result;

}
Cosi come l'ho scritto funziona ma non rispetta le specifiche dell'homework. Infatti i metodi put e get devono avere come parametri buffer_t* e msg_t*(per intenderci put_bloccante(buffer_t* buffer,msg_t* msg))
Io ho provato a scrivere il metodo put_bloccante in questo modo:
codice:
msg_t* put_bloccante(buffer_t *buffer,msg_t* msg){

        msg = msg_init_string("Messaggio");
        pthread_mutex_lock(&buffer->mutex);

        while(buffer->K==buffer->N){
            printf("Il Produttore è in attesa che il buffer sia vuoto\n");
            pthread_cond_wait(&buffer->non_pieno,&buffer->mutex);


        }

        buffer->buffer_circolare[buffer->D]=msg_copy_string(msg);
        printf("Il produttore inserisce il messaggio\n");
        buffer->D=(buffer->D+1)%buffer->N;
        buffer->K=buffer->K+1;

        pthread_cond_signal(&buffer->non_vuoto);
        pthread_mutex_unlock(&buffer->mutex);
        return msg;

    /**}else return BUFFERERROR;*/

}
Ma se eseguo tale metodo(invocandolo nel main mediante pthread_create(&th1,NULL,put_bloccante,(buffer_vuo to,msg))) non mi viene visualizzato in output alcun tipo di messaggio.
Volevo sapere se qualcuno mi potesse aiutare nel trovare l'errore