Search code examples
cpthreadspthread-cleanup

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;   

    } 

Solution

  • 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.