Could someone take a look? Further details could be found at https://bugzilla.stlinux.com/show_bug.cgi?id=21083 there is also a test case spotting the issue.
> -----Original Message----- > From: Carmelo AMOROSO [mailto:carmelo.amor...@st.com] > Sent: Wednesday, September 12, 2012 4:55 PM > To: uclibc@uclibc.org > Cc: Filippo ARCIDIACONO; Carmelo Amoroso > Subject: [PATCH] libc: make I/O locking cancel-safe with futexes > > From: Filippo ARCIDIACONO <filippo.arcidiac...@st.com> > > Current implementation of I/O locking macros using futexes are not > cancel safe, as if a thread is cancelled while doing IO operations, > it does not release the lock on the IO stream. So following > attempts to acquire the IO stream's lock would dead-lock. > In order to make it cancel-safe, it needs to rely upon the > pthread_cleanup push & pop protocol, as it is already done for > the pthread_mutex counterpart. > > Signed-off-by: Filippo Arcidiacono <filippo.arcidiac...@st.com> > Signed-off-by: Carmelo Amoroso <carmelo.amor...@st.com> > --- > libc/stdio/Makefile.in | 3 ++ > libc/stdio/io_lock_unlock.c | 16 ++++++++++++++ > libc/sysdeps/linux/common/bits/uClibc_mutex.h | 23 +++++++++++++--- > ---- > libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h | 2 + > 4 files changed, 36 insertions(+), 8 deletions(-) > create mode 100644 libc/stdio/io_lock_unlock.c > > diff --git a/libc/stdio/Makefile.in b/libc/stdio/Makefile.in > index ff77bcb..4652036 100644 > --- a/libc/stdio/Makefile.in > +++ b/libc/stdio/Makefile.in > @@ -52,6 +52,9 @@ endif > > # pthread functions > CSRC += flockfile.c ftrylockfile.c funlockfile.c > +ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y) > +CSRC += io_lock_unlock.c > +endif > > # Functions with unlocked versions > CUSRC := \ > diff --git a/libc/stdio/io_lock_unlock.c b/libc/stdio/io_lock_unlock.c > new file mode 100644 > index 0000000..b414264 > --- /dev/null > +++ b/libc/stdio/io_lock_unlock.c > @@ -0,0 +1,16 @@ > +/* > + * Copyright (C) 2012 STMicroelectronics, Ltd > + * > + * Author(s): Filippo Arcidiacono <filippo.arcidiac...@st.com> > + * > + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball > + */ > + > +#include <bits/stdio-lock.h> > + > +/* Function wrapper needed for I/O locking macros. */ > + > +void IO_lock_unlock (_IO_lock_t *lock) > +{ > + _IO_lock_unlock (*lock); > +} > diff --git a/libc/sysdeps/linux/common/bits/uClibc_mutex.h > b/libc/sysdeps/linux/common/bits/uClibc_mutex.h > index 94597e8..c2a1cc1 100644 > --- a/libc/sysdeps/linux/common/bits/uClibc_mutex.h > +++ b/libc/sysdeps/linux/common/bits/uClibc_mutex.h > @@ -12,6 +12,7 @@ > > #ifdef __UCLIBC_HAS_THREADS__ > > + > #include <pthread.h> > #ifdef _LIBC > #include <bits/uClibc_pthread.h> > @@ -79,15 +80,21 @@ > #define __UCLIBC_IO_MUTEX_INIT(M) _IO_lock_t M = > _IO_lock_initializer > #define __UCLIBC_IO_MUTEX_EXTERN(M) extern _IO_lock_t M > > -#define __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,C) \ > - if (C) { > \ > - _IO_lock_lock(M); > \ > - } > +#define __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,C) > \ > + do { > \ > + struct _pthread_cleanup_buffer > __infunc_pthread_cleanup_buffer; \ > + int __infunc_need_locking = (C); > \ > + if (__infunc_need_locking) { > \ > + > _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer > , \ > + (void (*) (void > *))IO_lock_unlock, \ > + &(M)); > \ > + _IO_lock_lock((M)); > \ > + } > \ > + ((void)0) > + > > -#define __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,C) \ > - if (C) { > \ > - _IO_lock_unlock(M); > \ > - } > +#define __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,C) > \ > + __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) > > #define __UCLIBC_IO_MUTEX_AUTO_LOCK(M,A,V) \ > __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,((A=(V))) == > 0) > diff --git a/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h > b/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h > index 3437e61..c742644 100644 > --- a/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h > +++ b/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h > @@ -29,6 +29,8 @@ > > typedef struct { int lock; int cnt; void *owner; } _IO_lock_t; > > +void IO_lock_unlock (_IO_lock_t *lock); > + > #define _IO_lock_initializer { LLL_LOCK_INITIALIZER, 0, NULL } > > #define _IO_lock_init(_name) \ > -- > 1.7.4.4 _______________________________________________ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc