aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-01-11 08:10:42 +0000
committerUlrich Drepper <drepper@redhat.com>2006-01-11 08:10:42 +0000
commitaf047cff7142b324f9236a745ee9cafb400434ba (patch)
treefa3b4845c252ff7121bcb220944de144c9f1dd35 /libio/genops.c
parent* libio/genops.c (_IO_unbuffer_write): Don't always free the (diff)
downloadglibc-af047cff7142b324f9236a745ee9cafb400434ba.tar.gz
glibc-af047cff7142b324f9236a745ee9cafb400434ba.tar.bz2
glibc-af047cff7142b324f9236a745ee9cafb400434ba.zip
* libio/genops.c (_IO_unbuffer_write): Give concurrently running
threads the chance to work correctly by trying to lock the stream. If this does not work, proceed without locking.
Diffstat (limited to 'libio/genops.c')
-rw-r--r--libio/genops.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/libio/genops.c b/libio/genops.c
index 3deb044a08..da29ade4e6 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -947,6 +947,16 @@ _IO_unbuffer_write (void)
/* Iff stream is un-orientated, it wasn't used. */
&& fp->_mode != 0)
{
+ int cnt;
+#define MAXTRIES 2
+ for (cnt = 0; cnt < MAXTRIES; ++cnt)
+ if (_IO_lock_trylock (*fp->_lock) == 0)
+ break;
+ else
+ /* Give the other thread time to finish up its use of the
+ stream. */
+ __sched_yield ();
+
if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
{
fp->_flags |= _IO_USER_BUF;
@@ -958,6 +968,9 @@ _IO_unbuffer_write (void)
}
_IO_SETBUF (fp, NULL, 0);
+
+ if (cnt < MAXTRIES)
+ _IO_lock_unlock (*fp->_lock);
}
/* Make sure that never again the wide char functions can be