aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Yano <takashi.yano@nifty.ne.jp>2025-07-16 23:21:17 +0900
committerTakashi Yano <takashi.yano@nifty.ne.jp>2025-07-17 00:14:42 +0900
commite8bc312a2d32a465260e38f948d91f2847a1d00a (patch)
treeb3e03fb8b6d0e874f72d739399651a7d578a2977
parent3dfa6af3a41b71cacbcf9cf7495c4032845383d4 (diff)
downloadnewlib-e8bc312a2d32a465260e38f948d91f2847a1d00a.zip
newlib-e8bc312a2d32a465260e38f948d91f2847a1d00a.tar.gz
newlib-e8bc312a2d32a465260e38f948d91f2847a1d00a.tar.bz2
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>
-rw-r--r--newlib/libc/stdio/fclose.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/newlib/libc/stdio/fclose.c b/newlib/libc/stdio/fclose.c
index 983ae2c..4c81cbf 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);