#include <pthread.h>
#include <sched.h>
#include <stdio.h>

extern "C" void thr_yield(void);

void thr_yield(void)
{
	printf("thr_yield() called\n");
}

//extern "C" void printf(...);

struct X {
	int x;
	X(int i) {
		x = i;
		printf("X(%d) constructed.\n", i);
	}
	~X() {
		printf("X(%d) destroyed.\n", x);
	}
};

void
free_res(void *i)
{
	printf("Freeing `%d`\n", i);
}

char *f2(int i)
{
	try {
		X dummy(i);
		pthread_cleanup_push(free_res, (void *)i);

		if (i == 50) {
			pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
			pthread_testcancel();
		}

		f2(i + 1);
		pthread_cleanup_pop(0);

	} catch (int) {
		printf("Error: In handler.\n");
	}

	return "f2";
}

void *
thread2(void *tid)
{
	void *sts;
	printf("I am new thread :%d\n", pthread_self());
	pthread_cancel((pthread_t)tid);
	pthread_join((pthread_t)tid, &sts);
	printf("main thread cancelled due to %d\n", sts);
	return (sts);
}

main()
{
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
	pthread_create(NULL, NULL, thread2, (void *)pthread_self());
	thr_yield();
	printf("Returned from %s\n", f2(0));
}