diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2012-05-30 08:58:42 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2012-05-30 08:58:42 +0000 |
commit | 4aa28d8ae279329f2b46c92e05b0bf457f07b9af (patch) | |
tree | ff4d1723c92ad0f708643f70125baf16e2beaf49 /newlib/libc/stdio/local.h | |
parent | 75b6133098753a31b722f94b86e95b11323735f0 (diff) | |
download | cygnal-4aa28d8ae279329f2b46c92e05b0bf457f07b9af.tar.gz cygnal-4aa28d8ae279329f2b46c92e05b0bf457f07b9af.tar.bz2 cygnal-4aa28d8ae279329f2b46c92e05b0bf457f07b9af.zip |
* libc/stdio/local.h (_newlib_flockfile_start): New macro to
secure stream related critical section against thread cancellation.
(_newlib_flockfile_exit): Ditto.
(_newlib_sfp_lock_end): Ditto.
(_newlib_sfp_lock_start): Ditto for the list of streams.
(_newlib_sfp_lock_exit): Ditto.
(_newlib_sfp_lock_end): Ditto.
Use aforementioned macros in place of _flockfile/_funlockfile
and __sfp_lock_acquire/__sfp_lock_release throughout the code.
* libc/stdio/fclose.c: Explicitely disable and re-enable thread
cancellation. Explain why.
* libc/stdio/freopen.c: Ditto.
* libc/stdio64/freopen64.c: Ditto.
Diffstat (limited to 'newlib/libc/stdio/local.h')
-rw-r--r-- | newlib/libc/stdio/local.h | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h index 187f7d858..aeeb0e8ee 100644 --- a/newlib/libc/stdio/local.h +++ b/newlib/libc/stdio/local.h @@ -32,6 +32,83 @@ # include <io.h> #endif +/* The following macros are supposed to replace calls to _flockfile/_funlockfile + and __sfp_lock_acquire/__sfp_lock_release. In case of multi-threaded + environments using pthreads, it's not sufficient to lock the stdio functions + against concurrent threads accessing the same data, the locking must also be + secured against thread cancellation. + + The below macros have to be used in pairs. The _newlib_XXX_start macro + starts with a opening curly brace, the _newlib_XXX_end macro ends with a + closing curly brace, so the start macro and the end macro mark the code + start and end of a critical section. In case the code leaves the critical + section before reaching the end of the critical section's code end, use + the appropriate _newlib_XXX_exit macro. */ + +#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS) +#include <pthread.h> + +/* Start a stream oriented critical section: */ +# define _newlib_flockfile_start(_fp) \ + { \ + int __oldfpcancel; \ + pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldfpcancel); \ + _flockfile (_fp) + +/* Exit from a stream oriented critical section prematurely: */ +# define _newlib_flockfile_exit(_fp) \ + _funlockfile (_fp); \ + pthread_setcancelstate (__oldfpcancel, &__oldfpcancel); + +/* End a stream oriented critical section: */ +# define _newlib_flockfile_end(_fp) \ + _funlockfile (_fp); \ + pthread_setcancelstate (__oldfpcancel, &__oldfpcancel); \ + } + +/* Start a stream list oriented critical section: */ +# define _newlib_sfp_lock_start() \ + { \ + int __oldsfpcancel; \ + pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldsfpcancel); \ + __sfp_lock_acquire () + +/* Exit from a stream list oriented critical section prematurely: */ +# define _newlib_sfp_lock_exit() \ + __sfp_lock_release (); \ + pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel); + +/* End a stream list oriented critical section: */ +# define _newlib_sfp_lock_end() \ + __sfp_lock_release (); \ + pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel); \ + } + +#else /* __SINGLE_THREAD__ || !_POSIX_THREADS */ + +# define _newlib_flockfile_start(_fp) \ + { \ + _flockfile(_fp) + +# define _newlib_flockfile_exit(_fp) \ + _funlockfile(_fp); \ + +# define _newlib_flockfile_end(_fp) \ + _funlockfile(_fp); \ + } + +# define _newlib_sfp_lock_start() \ + { \ + __sfp_lock_acquire () + +# define _newlib_sfp_lock_end() \ + __sfp_lock_release (); + +# define _newlib_sfp_lock_end() \ + __sfp_lock_release (); \ + } + +#endif /* !__SINGLE_THREAD__ && _POSIX_THREADS */ extern u_char *_EXFUN(__sccl, (char *, u_char *fmt)); extern int _EXFUN(__svfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); |