From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Andreas Schwab Newsgroups: gmane.comp.lib.glibc.alpha Subject: [PATCH] Always do locking when accessing streams (bug 15142) Date: Tue, 30 Jan 2018 17:58:28 +0100 Message-ID: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1517331410 26191 195.159.176.226 (30 Jan 2018 16:56:50 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 30 Jan 2018 16:56:50 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.91 (gnu/linux) To: libc-alpha@sourceware.org Original-X-From: libc-alpha-return-89828-glibc-alpha=m.gmane.org@sourceware.org Tue Jan 30 17:56:45 2018 Return-path: Envelope-to: glibc-alpha@blaine.gmane.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:mime-version :content-type; q=dns; s=default; b=HLs9F7cd8gmezkmQK6kAXoE2e0cRW twHOFGsWLwoSw0xK0AaR9AkKttJ9tlAFOOKVTUNelXEGegti3F/8nZy1eSf6baTI YRKugx6nIE5aNtaF9Hysr+js1z7Oz+BECP/Au7hBfldBDR1tlQQhBZ+3BOrALFPv UMlXuOk7s+01yI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:mime-version :content-type; s=default; bh=ZksQgeSUwgsQDL3B1IiCu9gvP0Y=; b=ORo J+ZwKyZmcUEmXnDkOTzMXwEe3keOoRY7idr5SzBI6p47MTP7mPNAwBNXhtCp8+gK EJLhwIVEWoplL4HsSEgMKMoH2J/c8xDM3pe0Gsz2+eSL9Q26XEnSj3jF4lW/UgQz 9msREsAvvSYj1MmGABg0+kDcsXe5qpWljeXhtMdU= Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Original-Sender: libc-alpha-owner@sourceware.org Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=locked X-HELO: mx2.suse.de X-Yow: Sorry, wrong ZIP CODE!! Xref: news.gmane.org gmane.comp.lib.glibc.alpha:82178 Archived-At: Received: from server1.sourceware.org ([209.132.180.131] helo=sourceware.org) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1egZCx-0005bG-EV for glibc-alpha@blaine.gmane.org; Tue, 30 Jan 2018 17:56:32 +0100 Received: (qmail 72835 invoked by alias); 30 Jan 2018 16:58:32 -0000 Received: (qmail 72823 invoked by uid 89); 30 Jan 2018 16:58:32 -0000 During exit, skip files that are currently locked to avoid deadlock. [BZ #15142] * include/bits/libio.h (_IO_ftrylockfile): Define. * 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_lockp): Don't declare. --- include/bits/libio.h | 4 ++++ libio/genops.c | 54 +++++++++++++++++++++++++++------------------------- libio/libioP.h | 1 - 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/include/bits/libio.h b/include/bits/libio.h index 572395d5ff..0743bf5356 100644 --- a/include/bits/libio.h +++ b/include/bits/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 */ diff --git a/libio/genops.c b/libio/genops.c index d6f8050669..21ebf3c2df 100644 --- a/libio/genops.c +++ b/libio/genops.c @@ -744,8 +744,8 @@ _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; @@ -758,7 +758,16 @@ _IO_flush_all_lockp (int do_lock) 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) @@ -769,8 +778,7 @@ _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; } @@ -787,7 +795,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) @@ -852,22 +860,18 @@ _IO_unbuffer_all (void) 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; @@ -881,16 +885,14 @@ _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 @@ -916,9 +918,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. diff --git a/libio/libioP.h b/libio/libioP.h index 068ceb2615..732db5d6a8 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -486,7 +486,6 @@ extern int _IO_new_do_write (_IO_FILE *, const char *, _IO_size_t); 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); -- 2.16.1 -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."