Michał Ziobro Michał Ziobro - 4 months ago 23
C Question

pthread_cancel() and using cleanup handlers.

I have a problem with pthread cancellation and using cleanup handlers.
In POSIX library there are two functions:
pthread_cleanup_push and pthread_cleanup_pop.
The problem is that they aren't functions but macros!
Moreover it seems that they have to be placed in pairs i.e. for each push, there must be also pop. But I seems it is a little odd.

Suppose I have such code structure:

{
pthread_mutex_lock(&mutex);
pthread_cleanup_push(cleanup_mutex, &mutex);

// any code that can be cancellation point

while(/*some condition *) {
// any code that cancellation point

// 1. signaled -> thread given mutex
// 2. timeout -> thread given mutex
// 3. canceled -> thread given mutex and than cleanup handlers
if(pthread_cond_timedwait(&cond, &mutex, &abstimeout) == ETIMEDOUT) {

/*** HERE SHOULD BE pthread_cleanup_pop(0)! But it cannot be placed! case 2)***/
pthread_mutex_unlock(&mutex);
return NULL;
}
}
// any code that can be cancellation point

// consume something

// any code that can be cancellation point

pthread_cleanup_pop(0); // takes care of case 1)
pthread_mutex_unlock(&mutex);

return something;

}

Answer

Yeah, it's a little odd, but that's how it is. Worst case, you can use a goto to jump to a return statement in the appropriate scope. But there's usually a more natural way to do it.