This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
libio plays loose with locking
- To: gcc-patches@gcc.gnu.org
- Subject: libio plays loose with locking
- From: Andreas Schwab <schwab@suse.de>
- Date: 05 Aug 1999 16:31:02 +0200
In many places inside iostream the call to isfx is missing, so that the
stream remains locked after the function returns. You'll only notice it
when you use threads.
1999-08-05 Andreas Schwab <schwab@suse.de>
* iostream.cc: Add missing calls to isfx and setup a cleanup
region for the locked stream.
* iostream.h: Likewise.
* isgetline.cc: Likewise.
* isgetsb.cc: Likewise.
* isscan.cc: Likewise.
Index: iostream.cc
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/libio/iostream.cc,v
retrieving revision 1.9
diff -u -a -r1.9 iostream.cc
--- iostream.cc 1998/02/24 20:09:51 1.9
+++ iostream.cc 1999/08/05 14:27:55
@@ -71,6 +71,8 @@
istream& istream::get(char& c)
{
if (ipfx1()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
int ch = _strbuf->sbumpc();
if (ch == EOF) {
set(ios::eofbit|ios::failbit);
@@ -80,6 +82,8 @@
c = (char)ch;
_gcount = 1;
}
+ isfx();
+ _IO_cleanup_region_end (0);
}
else
_gcount = 0;
@@ -102,10 +106,12 @@
{
_gcount = 0;
if (ipfx1()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
register streambuf* sb = _strbuf;
if (delim == EOF) {
_gcount = sb->ignore(n);
- return *this;
+ goto unlock;
}
for (;;) {
#if 0
@@ -122,6 +128,9 @@
if (ch == delim)
break;
}
+ unlock:
+ isfx();
+ _IO_cleanup_region_end (0);
}
return *this;
}
@@ -129,9 +138,13 @@
istream& istream::read(char *s, streamsize n)
{
if (ipfx1()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
_gcount = _strbuf->sgetn(s, n);
if (_gcount != n)
set(ios::failbit|ios::eofbit);
+ isfx();
+ _IO_cleanup_region_end (0);
}
else
_gcount = 0;
@@ -184,11 +197,15 @@
istream& istream::operator>>(char& c)
{
if (ipfx0()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
int ch = _strbuf->sbumpc();
if (ch == EOF)
set(ios::eofbit|ios::failbit);
else
c = (char)ch;
+ isfx();
+ _IO_cleanup_region_end (0);
}
return *this;
}
@@ -200,6 +217,8 @@
int w = width(0);
if (ipfx0())
{
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
register streambuf* sb = _strbuf;
for (;;)
{
@@ -219,6 +238,8 @@
}
if (p == ptr)
set(ios::failbit);
+ isfx();
+ _IO_cleanup_region_end (0);
}
*p = '\0';
return *this;
@@ -234,6 +255,9 @@
{
if (!stream.ipfx0())
return 0;
+ int retval;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ stream._strbuf);
register streambuf* sb = stream.rdbuf();
int base = 10;
int ndigits = 0;
@@ -254,7 +278,7 @@
ch = sb->sbumpc();
if (ch == EOF) {
val = 0;
- return 1;
+ goto unlock;
}
if (ch == 'x' || ch == 'X') {
base = 16;
@@ -290,19 +314,26 @@
if (ndigits == 0)
goto fail;
else
- return 1;
+ goto unlock;
}
ndigits++;
val = base * val + digit;
ch = sb->sbumpc();
}
- return 1;
+ unlock:
+ retval = 1;
+ goto out;
fail:
stream.set(ios::failbit);
- return 0;
+ retval = 0;
+ goto out;
eof_fail:
stream.set(ios::failbit|ios::eofbit);
- return 0;
+ retval = 0;
+ out:
+ stream.isfx();
+ _IO_cleanup_region_end (0);
+ return retval;
}
#define READ_INT(TYPE) \
@@ -334,6 +365,8 @@
{
if (ipfx0())
{
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
#if _G_HAVE_LONG_DOUBLE_IO
scan("%Lg", &x);
#else
@@ -341,6 +374,8 @@
scan("%lg", &y);
x = y;
#endif
+ isfx();
+ _IO_cleanup_region_end (0);
}
return *this;
}
@@ -348,20 +383,34 @@
istream& istream::operator>>(double& x)
{
if (ipfx0())
+ {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
scan("%lg", &x);
+ isfx();
+ _IO_cleanup_region_end (0);
+ }
return *this;
}
istream& istream::operator>>(float& x)
{
if (ipfx0())
+ {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
scan("%g", &x);
+ isfx();
+ _IO_cleanup_region_end (0);
+ }
return *this;
}
istream& istream::operator>>(register streambuf* sbuf)
{
if (ipfx0()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
register streambuf* inbuf = rdbuf();
// FIXME: Should optimize!
for (;;) {
@@ -375,6 +424,8 @@
break;
}
}
+ isfx();
+ _IO_cleanup_region_end (0);
}
return *this;
}
@@ -789,8 +840,8 @@
if (flags() & ios::left && padding > 0) // Left adjustment.
if (_IO_padn(sbuf, fill_char, padding) != padding)
set(ios::badbit);
- osfx();
failed:
+ osfx();
_IO_cleanup_region_end (0);
}
return *this;
Index: iostream.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/libio/iostream.h,v
retrieving revision 1.3
diff -u -a -r1.3 iostream.h
--- iostream.h 1997/09/16 16:00:28 1.3
+++ iostream.h 1999/08/05 14:27:55
@@ -173,6 +173,7 @@
int get() { if (!ipfx1()) return EOF;
else { int ch = _strbuf->sbumpc();
if (ch == EOF) set(ios::eofbit);
+ isfx();
return ch;
} }
int peek();
Index: isgetline.cc
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/libio/isgetline.cc,v
retrieving revision 1.3
diff -u -a -r1.3 isgetline.cc
--- isgetline.cc 1998/04/19 21:14:32 1.3
+++ isgetline.cc 1999/08/05 14:27:55
@@ -37,6 +37,8 @@
int ch;
if (ipfx1())
{
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
streambuf *sb = rdbuf();
_gcount = _IO_getline_info(sb, buf, len - 1, delim, -1, &ch);
if (ch != EOF)
@@ -48,6 +50,8 @@
set(ios::failbit);
sb->sungetc(); // Leave delimiter unread.
}
+ isfx();
+ _IO_cleanup_region_end (0);
}
else
ch = EOF;
@@ -67,11 +71,15 @@
}
if (ipfx1())
{
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
streambuf *sbuf = rdbuf();
int ch;
_gcount = _IO_getline_info(sbuf, buf, len - 1, delim, -1, &ch);
if (_gcount == 0 && ch == EOF)
set(ios::failbit|ios::eofbit);
+ isfx();
+ _IO_cleanup_region_end (0);
}
buf[_gcount] = '\0';
return *this;
@@ -123,6 +131,8 @@
istream& istream::gets(char **s, char delim /* = '\n' */)
{
if (ipfx1()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
long size = 0;
streambuf *sb = rdbuf();
*s = _sb_readline (sb, size, delim);
@@ -132,6 +142,8 @@
if (_gcount == 0)
set(ios::failbit);
}
+ isfx();
+ _IO_cleanup_region_end (0);
}
else {
_gcount = 0;
Index: isgetsb.cc
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/libio/isgetsb.cc,v
retrieving revision 1.1.1.1
diff -u -a -r1.1.1.1 isgetsb.cc
--- isgetsb.cc 1997/08/21 22:58:19 1.1.1.1
+++ isgetsb.cc 1999/08/05 14:27:55
@@ -31,6 +31,8 @@
_gcount = 0;
if (ipfx1())
{
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
register streambuf* isb = rdbuf();
for (;;)
{
@@ -54,6 +56,8 @@
if (delimp != NULL)
break;
}
+ isfx();
+ _IO_cleanup_region_end (0);
}
return *this;
}
Index: isscan.cc
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/libio/isscan.cc,v
retrieving revision 1.1.1.1
diff -u -a -r1.1.1.1 isscan.cc
--- isscan.cc 1997/08/21 22:58:19 1.1.1.1
+++ isscan.cc 1999/08/05 14:27:55
@@ -29,10 +29,14 @@
istream& istream::scan(const char *format ...)
{
if (ipfx0()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
va_list ap;
va_start(ap, format);
_strbuf->vscan(format, ap, this);
va_end(ap);
+ isfx();
+ _IO_cleanup_region_end (0);
}
return *this;
}
@@ -40,6 +44,12 @@
istream& istream::vscan(const char *format, _IO_va_list args)
{
if (ipfx0())
+ {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
_strbuf->vscan(format, args, this);
+ isfx();
+ _IO_cleanup_region_end (0);
+ }
return *this;
}
--
Andreas Schwab "And now for something
schwab@suse.de completely different."
SuSE GmbH, Schanzäckerstr. 10, D-90443 Nürnberg