Cancellation


FOO TIMEDWAIT

struct data {
	int arg;
	int ret;
	int sleeptime;
	pthread_t doer;
	pthread_t sleeper;
	pthread_mutex_t mutex;
};

void * doer(struct data * data)
{
	data->ret = foo(data->arg);
	pthread_mutex_lock(data->mutex);
	pthread_cleanup_push(pthread_mutex_unlock, data->mutex);
	pthread_testcancel();
	pthread_cancel(data->sleeper);
	pthread_cleanup_pop(1);
	return(NULL);
}
void * sleeper(struct data * data)
{
	sleep(data->sleeptime);
	pthread_mutex_lock(data->mutex);
	pthread_cleanup_push(pthread_mutex_unlock, data->mutex);
	pthread_testcancel();
	pthread_cancel(data->doer);
	pthread_cleanup_pop(1);
	return(NULL);
}

int foo_timedwait(int arg, int sleeptime)
{
	struct foo_data data;
	void * status;

	data.arg = arg;
	data.sleeptime = sleeptime;
	pthread_mutex_lock(&data.mutex);
	pthread_create(&data.sleeper, NULL, sleeper, &data);
	pthread_create(&data.doer, NULL, doer, &data); 
	pthread_mutex_unlock(&data.mutex);

	{
		pthread_cleanup_push(pthread_cancel, data.doer);
		pthread_cleanup_push(pthread_detach, data.doer);
		{
			pthread_cleanup_push(pthread_cancel, data.sleeper);
			pthread_cleanup_push(pthread_detach, data.sleeper);
			pthread_join(data.sleeper, &status);
			pthred_cleanup_pop(0);
			pthred_cleanup_pop(0);
		}
		pthread_join(data.doer, &status);
		pthread_cleanup_pop(0);
		pthread_cleanup_pop(0);
	}

	if (status == PTHREAD_CANCELLED) {
		ret = ETIMEDOUT;
	else
		ret = data.ret;
	return(ret);
}


[TOP] [BACK] [FORWARD]


Prepared by Chris Provenzano (proven@mit.edu)