[newlib-cygwin/cygwin-3_6-branch] newlib: fclose: Use sfp lock while fp lock is active

Takashi Yano tyan0@sourceware.org
Wed Jul 16 15:16:50 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=5fb125d018b00d0a4ece4d1f2be7c5e60f8280f0

commit 5fb125d018b00d0a4ece4d1f2be7c5e60f8280f0
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date:   Wed Jul 16 23:21:17 2025 +0900

    newlib: fclose: Use sfp lock while fp lock is active
    
    With the commit 656df313e08a, if a thread acquires sfp lock after
    another thread calls fclose() and fp lock is acquired, the first
    thread falls into deadlock if it tries to acquire fp lock. This can
    happen if the first thread calls __sfp_lock_all() while the second
    thread calls fclose().
    
    This patch reverts the changes for newlib/libc/stdio/fclose.c in
    the commit 656df313e08a.
    
    Addresses: https://cygwin.com/pipermail/cygwin/2025-June/258323.html
    Fixes: 656df313e08a ("* libc/stdio/fclose.c: Only use sfp lock to guard non-atomic changes of flags and fp lock.")
    Reported-by: Takashi Yano <takashi.yano@nifty.ne.jp>
    Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
    Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
    (cherry picked from commit e8bc312a2d32a465260e38f948d91f2847a1d00a)

Diff:
---
 newlib/libc/stdio/fclose.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/newlib/libc/stdio/fclose.c b/newlib/libc/stdio/fclose.c
index 983ae2cc4..4c81cbf4b 100644
--- a/newlib/libc/stdio/fclose.c
+++ b/newlib/libc/stdio/fclose.c
@@ -72,6 +72,7 @@ _fclose_r (struct _reent *rptr,
   int __oldcancel;
   pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldcancel);
 #endif
+  __sfp_lock_acquire ();
   if (!(fp->_flags2 & __SNLK))
     _flockfile (fp);
 
@@ -79,6 +80,7 @@ _fclose_r (struct _reent *rptr,
     {
       if (!(fp->_flags2 & __SNLK))
 	_funlockfile (fp);
+      __sfp_lock_release ();
 #ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
       pthread_setcancelstate (__oldcancel, &__oldcancel);
 #endif
@@ -101,7 +103,6 @@ _fclose_r (struct _reent *rptr,
     FREEUB (rptr, fp);
   if (HASLB (fp))
     FREELB (rptr, fp);
-  __sfp_lock_acquire ();
   fp->_flags = 0;		/* release this FILE for reuse */
   if (!(fp->_flags2 & __SNLK))
     _funlockfile (fp);


More information about the Newlib-cvs mailing list