Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.1:Rings:0-Bootstrap
glibc
fix-locking-in-_IO_cleanup.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fix-locking-in-_IO_cleanup.patch of Package glibc
Always do locking when accessing streams [BZ #15142] * include/libio.h (_IO_ftrylockfile) [_IO_MTSAVE_IO]: Define. * libio/genops.c (_IO_list_all_stamp): Delete. All uses removed. * libio/genops.c (_IO_flush_all_lockp): Make static. Rename argument to skip_locked, callers changed. Skip files that are locked if skip_locked. (_IO_unbuffer_all): Lock files before access, but skip locked files. * libio/libioP.h (_IO_flush_all_all_lockp): Don't declare. Index: glibc-2.26/include/libio.h =================================================================== --- glibc-2.26.orig/include/libio.h +++ glibc-2.26/include/libio.h @@ -33,11 +33,15 @@ libc_hidden_proto (_IO_vfscanf) if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_lock_lock (*(_fp)->_lock) # define _IO_funlockfile(_fp) \ if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_lock_unlock (*(_fp)->_lock) +# define _IO_ftrylockfile(_fp) \ + (((_fp)->_flags & _IO_USER_LOCK) == 0 ? _IO_lock_trylock (*(_fp)->_lock) : 0) # else # define _IO_flockfile(_fp) \ if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_flockfile (_fp) # define _IO_funlockfile(_fp) \ if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (_fp) +# define _IO_ftrylockfile(_fp) \ + (((_fp)->_flags & _IO_USER_LOCK) == 0 ? _IO_ftrylockfile (_fp) : 0) # endif #endif /* _IO_MTSAFE_IO */ Index: glibc-2.26/libio/genops.c =================================================================== --- glibc-2.26.orig/libio/genops.c +++ glibc-2.26/libio/genops.c @@ -38,10 +38,6 @@ static _IO_lock_t list_all_lock = _IO_lock_initializer; #endif -/* Used to signal modifications to the list of FILE decriptors. */ -static int _IO_list_all_stamp; - - static _IO_FILE *run_fp; #ifdef _IO_MTSAFE_IO @@ -69,16 +65,12 @@ _IO_un_link (struct _IO_FILE_plus *fp) if (_IO_list_all == NULL) ; else if (fp == _IO_list_all) - { - _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain; - ++_IO_list_all_stamp; - } + _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain; else for (f = &_IO_list_all->file._chain; *f; f = &(*f)->_chain) if (*f == (_IO_FILE *) fp) { *f = fp->file._chain; - ++_IO_list_all_stamp; break; } fp->file._flags &= ~_IO_LINKED; @@ -106,7 +98,6 @@ _IO_link_in (struct _IO_FILE_plus *fp) #endif fp->file._chain = (_IO_FILE *) _IO_list_all; _IO_list_all = fp; - ++_IO_list_all_stamp; #ifdef _IO_MTSAFE_IO _IO_funlockfile ((_IO_FILE *) fp); run_fp = NULL; @@ -789,25 +780,30 @@ _IO_get_column (_IO_FILE *fp) #endif -int -_IO_flush_all_lockp (int do_lock) +static int +_IO_flush_all_lockp (bool skip_locked) { int result = 0; struct _IO_FILE *fp; - int last_stamp; #ifdef _IO_MTSAFE_IO - __libc_cleanup_region_start (do_lock, flush_cleanup, NULL); - if (do_lock) - _IO_lock_lock (list_all_lock); + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); #endif - last_stamp = _IO_list_all_stamp; - fp = (_IO_FILE *) _IO_list_all; - while (fp != NULL) + for (fp = (_IO_FILE *) _IO_list_all; fp != NULL; fp = fp->_chain) { run_fp = fp; - if (do_lock) + if (skip_locked) + { + /* Skip files that are currently locked. */ + if (_IO_ftrylockfile (fp)) + { + run_fp = NULL; + continue; + } + } + else _IO_flockfile (fp); if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base) @@ -820,24 +816,13 @@ _IO_flush_all_lockp (int do_lock) && _IO_OVERFLOW (fp, EOF) == EOF) result = EOF; - if (do_lock) - _IO_funlockfile (fp); + _IO_funlockfile (fp); run_fp = NULL; - - if (last_stamp != _IO_list_all_stamp) - { - /* Something was added to the list. Start all over again. */ - fp = (_IO_FILE *) _IO_list_all; - last_stamp = _IO_list_all_stamp; - } - else - fp = fp->_chain; } #ifdef _IO_MTSAFE_IO - if (do_lock) - _IO_lock_unlock (list_all_lock); - __libc_cleanup_region_end (0); + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); #endif return result; @@ -848,7 +833,7 @@ int _IO_flush_all (void) { /* We want locking. */ - return _IO_flush_all_lockp (1); + return _IO_flush_all_lockp (false); } libc_hidden_def (_IO_flush_all) @@ -856,16 +841,13 @@ void _IO_flush_all_linebuffered (void) { struct _IO_FILE *fp; - int last_stamp; #ifdef _IO_MTSAFE_IO _IO_cleanup_region_start_noarg (flush_cleanup); _IO_lock_lock (list_all_lock); #endif - last_stamp = _IO_list_all_stamp; - fp = (_IO_FILE *) _IO_list_all; - while (fp != NULL) + for (fp = (_IO_FILE *) _IO_list_all; fp != NULL; fp = fp->_chain) { run_fp = fp; _IO_flockfile (fp); @@ -875,15 +857,6 @@ _IO_flush_all_linebuffered (void) _IO_funlockfile (fp); run_fp = NULL; - - if (last_stamp != _IO_list_all_stamp) - { - /* Something was added to the list. Start all over again. */ - fp = (_IO_FILE *) _IO_list_all; - last_stamp = _IO_list_all_stamp; - } - else - fp = fp->_chain; } #ifdef _IO_MTSAFE_IO @@ -919,24 +892,26 @@ static void _IO_unbuffer_all (void) { struct _IO_FILE *fp; + +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); +#endif + for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain) { + run_fp = fp; + /* Skip files that are currently locked. */ + if (_IO_ftrylockfile (fp)) + { + run_fp = NULL; + continue; + } + if (! (fp->_flags & _IO_UNBUFFERED) /* Iff stream is un-orientated, it wasn't used. */ && fp->_mode != 0) { -#ifdef _IO_MTSAFE_IO - int cnt; -#define MAXTRIES 2 - for (cnt = 0; cnt < MAXTRIES; ++cnt) - if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0) - break; - else - /* Give the other thread time to finish up its use of the - stream. */ - __sched_yield (); -#endif - if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) { fp->_flags |= _IO_USER_BUF; @@ -950,17 +925,20 @@ _IO_unbuffer_all (void) if (fp->_mode > 0) _IO_wsetb (fp, NULL, NULL, 0); - -#ifdef _IO_MTSAFE_IO - if (cnt < MAXTRIES && fp->_lock != NULL) - _IO_lock_unlock (*fp->_lock); -#endif } /* Make sure that never again the wide char functions can be used. */ fp->_mode = -1; + + _IO_funlockfile (fp); + run_fp = NULL; } + +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); +#endif } @@ -980,9 +958,9 @@ libc_freeres_fn (buffer_free) int _IO_cleanup (void) { - /* We do *not* want locking. Some threads might use streams but - that is their problem, we flush them underneath them. */ - int result = _IO_flush_all_lockp (0); + /* We want to skip locked streams. Some threads might use streams but + that is their problem, we don't flush those. */ + int result = _IO_flush_all_lockp (true); /* We currently don't have a reliable mechanism for making sure that C++ static destructors are executed in the correct order. Index: glibc-2.26/libio/libioP.h =================================================================== --- glibc-2.26.orig/libio/libioP.h +++ glibc-2.26/libio/libioP.h @@ -507,7 +507,6 @@ extern int _IO_new_do_write (_IO_FILE *, extern int _IO_old_do_write (_IO_FILE *, const char *, _IO_size_t); extern int _IO_wdo_write (_IO_FILE *, const wchar_t *, _IO_size_t); libc_hidden_proto (_IO_wdo_write) -extern int _IO_flush_all_lockp (int); extern int _IO_flush_all (void); libc_hidden_proto (_IO_flush_all) extern int _IO_cleanup (void);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor