#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <setjmp.h>
#include <signal.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
int ready = 0;
int done = 0;

sigjmp_buf env;

void
quit()
{
    siglongjmp(env, 1);
}

void *
thread(void *arg)
{
    sigset_t	 set;

    sigprocmask(SIG_SETMASK, NULL, &set);

    pthread_mutex_lock(&mutex);
    ready = 1;
    pthread_cond_signal(&cv);
    if (sigsetjmp(env, set) == 0) {
	signal(SIGINT, quit);
	pthread_cond_wait(&cv, &mutex);
    } else {
	TID tid;
	/* interrupted, should still hold the mutex */
	printf("Mutex state: \n");
	printf("count: %d\n", mutex.count);
	printf("owner: 0x%8.8x\n", mutex.owner);
	printf("queue: ");
	for (tid = mutex.waiters; tid; tid = tid->waitq) {
	    printf("%d\n", tid->owner);
	}
	printf("\n\n");
	printf("Cond state: \n");
	printf("queue: ");
	for (tid = cv.waiters; tid; tid = tid->waitq) {
	    printf("%d\n", tid->owner);
	}
	printf("\n\n");
    }
    pthread_mutex_unlock(&mutex);
    return NULL;
}

main()
{
   int args[2];
   pthread_t child;

   args[0] = 0;
   args[1] = 0;

   if (pthread_create(&child, NULL, &thread, NULL) != EOK) {
	printf("Couldn't create child\n");
   }

   pthread_mutex_lock(&mutex);
   while (!ready) {
	pthread_cond_wait(&cv, &mutex);
   }
   pthread_kill(child, SIGINT);
   pthread_mutex_unlock(&mutex);
   sleep(1);
   pthread_exit(0);
}
