newlib stdio and thread cancellation

Corinna Vinschen vinschen@redhat.com
Tue May 29 15:34:00 GMT 2012


Hi,

I'm just debugging a problem in Cygwin in terms of pthread cancellation.

Consider a scenario where multiple threads call printf.  The vfprintf
function is secured against concurrent usage of the same descriptor
by calling _flockfile/_funlockfile.

If pthread_cancel is called on a thread while it's executing printf,
_funlockfile is never called, because newlib's stdio functions neglect
to push/pop pthread cleanup handlers.

The result are spurious hangs, because the next stdio function on the
affected descriptor will hang in _flockfile.

While this might be of no interest for embedded targets, it's a really
serious problem for Cygwin or any other system implementing thread
cancellation.

There are two possible solutions:

- The target specific lock/unlock functions push and pop the cleanup
  handlers on their own.  I just implemented this for Cygwin but didn't
  check in yet.  This can become really awkward, depending on the
  underlying pthread implementation.

- The IMHO right thing to do would be to change newlib's stdio functions
  to call pthread_cleanup_push/pthread_cleanup_pop as necessary.  This
  could be combined with a matching ifdef, for instance:

    _flockfile (fp);
  #ifdef _POSIX_THREADS
    pthread_cleanup_push (flockfile_cleanup, (void *) fp);
  #endif

    [...]

  #ifdef _POSIX_THREADS
    pthread_cleanup_pop (1);
  #else
    _funlockfile (fp);
  #endif


Does anybody know another solution or would it be ok to add the
aforementioned functionality to newlib?


Corinna

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat



More information about the Newlib mailing list