about summary refs log tree commit diff
path: root/libio/genops.c
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
parent7876272372451b1cb0a7da9cfbbf9027550bccce (diff)
downloadglibc-af047cff7142b324f9236a745ee9cafb400434ba.tar.gz
glibc-af047cff7142b324f9236a745ee9cafb400434ba.tar.xz
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