[Bug 1195] New: behavior of pthread_cleanup_pop does not behave as described

bugzilla at busybox.net bugzilla at busybox.net
Sat Feb 27 03:03:28 UTC 2010


https://bugs.busybox.net/show_bug.cgi?id=1195

           Summary: behavior of pthread_cleanup_pop does not behave as
                    described
           Product: uClibc
           Version: 0.9.31
          Platform: Other
        OS/Version: Other
            Status: NEW
          Severity: normal
          Priority: P5
         Component: Threads
        AssignedTo: unassigned at uclibc.org
        ReportedBy: gondree at cs.ucdavis.edu
                CC: uclibc-cvs at uclibc.org
   Estimated Hours: 0.5


According to its description, pthread_cleanup_pop:
  "shall remove the routine at the top of the calling thread's cancellation 
  cleanup stack and optionally invoke it (if execute is non-zero)."

However, this implementation executes and then removes it from the cleanup
stack (order is reversed). This alternate behavior has the potential to cause
some code to deadlock. Example is below.

If you agree this is problematic, the solution is quite simple:
in, libpthread/linuxthread/cancel.c

void _pthread_cleanup_pop(struct _pthread_cleanup_buffer * buffer, int execute)
{
  pthread_descr self = thread_self();
  if (execute) buffer->__routine(buffer->__arg);
  THREAD_SETMEM(self, p_cleanup, buffer->__prev);
}

s/b
  THREAD_SETMEM(self, p_cleanup, buffer->__prev);
  if (execute) buffer->__routine(buffer->__arg);

Similar changes may be required in _pthread_cleanup_pop_restore

=======
Notional example of deadlocking code:
    If a thread is cancelled at point A, cancellation-handler 
    ch1() is executed for a second time (this time with the 
    mutex m acquired) which causes a deadlock.

void foo(void) {
    ...
    pthread_mutex_lock(&m);
    pthread_cleanup_push(&ch2, NULL);
    ...
    while(condition) {
        ....
        pthread_mutex_unlock(&m);
        pthread_cleanup_push(&ch1, NULL);
        ....
        pthread_cleanup_pop(1);
    }
    pthread_cleanup_pop(1);
}

void *ch1(void *p) {
    pthread_mutex_lock(&m);
    ....
    (A)
    ....
}

void *ch2(void *p) {
    pthread_mutex_unlock(&m);
    ....
}


-- 
Configure bugmail: https://bugs.busybox.net/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


More information about the uClibc-cvs mailing list