Make cout a little more thread-safe. This fixes http://llvm.org/bugs/show_bug.cgi?id=12158

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@185222 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Howard Hinnant 2013-06-28 21:40:28 +00:00
parent c1ecd97f00
commit ab135d7f4e

View File

@ -263,30 +263,31 @@ __stdoutbuf<_CharT>::overflow(int_type __c)
char_type __1buf; char_type __1buf;
if (!traits_type::eq_int_type(__c, traits_type::eof())) if (!traits_type::eq_int_type(__c, traits_type::eof()))
{ {
this->setp(&__1buf, &__1buf+1); __1buf = traits_type::to_char_type(__c);
*this->pptr() = traits_type::to_char_type(__c);
this->pbump(1);
if (__always_noconv_) if (__always_noconv_)
{ {
if (fwrite(this->pbase(), sizeof(char_type), 1, __file_) != 1) if (fwrite(&__1buf, sizeof(char_type), 1, __file_) != 1)
return traits_type::eof(); return traits_type::eof();
} }
else else
{ {
char* __extbe = __extbuf; char* __extbe = __extbuf;
codecvt_base::result __r; codecvt_base::result __r;
char_type* pbase = &__1buf;
char_type* pptr = pbase + 1;
char_type* epptr = pptr;
do do
{ {
const char_type* __e; const char_type* __e;
__r = __cv_->out(*__st_, this->pbase(), this->pptr(), __e, __r = __cv_->out(*__st_, pbase, pptr, __e,
__extbuf, __extbuf,
__extbuf + sizeof(__extbuf), __extbuf + sizeof(__extbuf),
__extbe); __extbe);
if (__e == this->pbase()) if (__e == pbase)
return traits_type::eof(); return traits_type::eof();
if (__r == codecvt_base::noconv) if (__r == codecvt_base::noconv)
{ {
if (fwrite(this->pbase(), 1, 1, __file_) != 1) if (fwrite(pbase, 1, 1, __file_) != 1)
return traits_type::eof(); return traits_type::eof();
} }
else if (__r == codecvt_base::ok || __r == codecvt_base::partial) else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
@ -296,15 +297,13 @@ __stdoutbuf<_CharT>::overflow(int_type __c)
return traits_type::eof(); return traits_type::eof();
if (__r == codecvt_base::partial) if (__r == codecvt_base::partial)
{ {
this->setp((char_type*)__e, this->pptr()); pbase = (char_type*)__e;
this->pbump(static_cast<int>(this->epptr() - this->pbase()));
} }
} }
else else
return traits_type::eof(); return traits_type::eof();
} while (__r == codecvt_base::partial); } while (__r == codecvt_base::partial);
} }
this->setp(0, 0);
} }
return traits_type::not_eof(__c); return traits_type::not_eof(__c);
} }