[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