#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include "error_msg.h"

void lock_mu( pthread_mutex_t *mu )
{
   int st;

   st = pthread_mutex_lock( mu );
   CHECK(st, "pthread_mutex_lock()");
   printf("\t\t>Child locked mutex\n");

   st = pthread_mutex_unlock( mu );
   CHECK(st, "pthread_mutex_unlock()");
   printf("\t\t>Child has unlocked mutex\n");

   pthread_exit( (void *) SUCCESS );
}

void
init_mu( pthread_mutex_t *mu )
{
   int st;

   st = pthread_mutex_init( mu, NULL );
   CHECK( st, "pthread_mutex_init()");
}

void
destroy_mu( pthread_mutex_t *mu )
{
   int st;

   st = pthread_mutex_destroy( mu );
   CHECK(st, "pthread_mutex_destroy()");
}

static pthread_mutex_t mutex;
static pthread_t th;

int 
main( int argc, char *argv[] )
{
   int st;

   init_mu( &mutex );

   /*
    *  --  Now, lock the mutex, and create a second thread.  The second
    *      thread will attempt to lock the same mutex, and block until
    *      the mutex is released.
    */
   st = pthread_mutex_lock( &mutex );
   CHECK(st, "pthread_mutex_lock()");

   printf("\t\t>Main has locked the mutex\n");

   /*
    *  --  This is the second thread that should block when it attempts to
    *      lock mu.
    */
   st = pthread_create( &th, NULL, (thread_proc_t)lock_mu, &mutex );
   CHECK(st, "pthread_create()");
   pthread_yield( NULL );

   /*
    *  --  Unlock the mutex
    */
   st = pthread_mutex_unlock( &mutex );
   CHECK(st, "pthread_mutex_unlock()");

   printf("\t\t>Main has unlocked the mutex\n");
   pthread_yield( NULL );

   destroy_mu( &mutex );
   return( EXIT_SUCCESS );
}
