/* gcc -Wall -Wextra -ansi -pedantic -o waittest -g3 waittest.c -l pthread */
#define _XOPEN_SOURCE 500 /* SUSv2 */
#include <pthread.h> /* pthread_mutex_lock() */
#include <assert.h> /* assert() */
#include <unistd.h> /* read() */
#include <stdio.h> /* fprintf() */
static pthread_mutex_t mutex;
static pthread_cond_t condvar;
static int *protected;
static void *
produce(void *ignored)
{
static int msg_to_publish;
int ret;
/* Produce message to publish. */
msg_to_publish = 1;
/* Publish it. */
ret = pthread_mutex_lock(&mutex); assert(0 == ret);
protected = &msg_to_publish;
ret = pthread_cond_signal(&condvar); assert(0 == ret);
ret = pthread_mutex_unlock(&mutex); assert(0 == ret);
return 0;
}
int
main(void)
{
int ret;
/* Initialize mutex. */
{
pthread_mutexattr_t mattr;
ret = pthread_mutexattr_init(&mattr); assert(0 == ret);
ret = pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_ERRORCHECK);
assert(0 == ret);
ret = pthread_mutex_init(&mutex, &mattr); assert(0 == ret);
ret = pthread_mutexattr_destroy(&mattr); assert(0 == ret);
}
/* Initialize condition variable. */
ret = pthread_cond_init(&condvar, 0); assert(0 == ret);
/* Co-operate with producer. */
{
pthread_t producer;
/* Start producer. */
ret = pthread_create(&producer, 0, produce, 0); assert(0 == ret);
/* Give producer plenty of time. */
{
ssize_t rd;
char unsigned cu;
rd = read(STDIN_FILENO, &cu, sizeof cu); assert(1 == rd);
}
/* Consume. */
{
int *saved;
ret = pthread_mutex_lock(&mutex); assert(0 == ret);
while (0 == protected) {
ret = pthread_cond_wait(&condvar, &mutex); assert(0 == ret);
}
saved = protected;
ret = pthread_mutex_unlock(&mutex); assert(0 == ret);
(void)fprintf(stdout, "%d\n", *saved);
}
/* Assimilate producer. */
ret = pthread_join(producer, 0); assert(0 == ret);
}
/* Clean up. */
ret = pthread_cond_destroy(&condvar); assert(0 == ret);
ret = pthread_mutex_destroy(&mutex); assert(0 == ret);
return 0;
}