This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Shouldn't ios_base::Init::Init() be reentrant?


On Mon, May 21, 2001 at 03:30:23AM +0200, Carlo Wood wrote:
> The following example would solve my problem,

Although nodoubt you already got the idea... but let me correct
the error I made that would cause a memory leak if only during
the allocation of the wide stream objects new would create an
Init object.

  void
  ios_base::Init::_S_ios_create(bool __sync)
  {
    int __bufsize = __sync ? 0 : static_cast<int>(BUFSIZ);

    // In order to allow reentrant calls to _S_ios_create (from
    // operator new) we first initialize dummy objects.
    fake_ostream tmp_cout, tmp_cerr, tmp_clog;
    fake_istream tmp_cin;
    
    new (&tmp_cout) ostream(new filebuf(stdout, ios_base::out, __bufsize));
    new (&tmp_cin) istream(new filebuf(stdin, ios_base::in, 1));
    new (&tmp_cerr) ostream(new filebuf(stderr, ios_base::out, __bufsize));
    new (&tmp_clog) ostream(cerr.rdbuf());

#ifdef _GLIBCPP_USE_WCHAR_T
    fake_wostream tmp_wcout, tmp_wcerr, tmp_wclog;
    fake_wistream tmp_wcin;

    new (&tmp_wcout) wostream(new wfilebuf(stdout, ios_base::out, __bufsize));
    new (&tmp_wcin) wistream(new wfilebuf(stdin, ios_base::in, 1));
    new (&tmp_wcerr) wostream(new wfilebuf(stderr, ios_base::out, __bufsize));
    new (&tmp_wclog) wostream(wcerr.rdbuf());
#endif

    if (_S_ios_base_init > 0)	// Was an Init object created from operator new?
    {
      delete tmp_cout.rdbuf();
      delete tmp_cin.rdbuf();
      delete tmp_cerr.rdbuf();
#ifdef _GLIBCPP_USE_WCHAR_T
      delete tmp_wcout.rdbuf();
      delete tmp_wcin.rdbuf();
      delete tmp_wcerr.rdbuf();
#endif
      return;
    }

    // NB: The file std_iostream.h creates the four standard files
    // with NULL buffers.  At this point, we swap out the dummy NULL
    // buffers with the real deal.

    memcpy(&cout, &tmp_cout, sizeof(cout));
    memcpy(&cin, &tmp_cin, sizeof(cin));
    memcpy(&cerr, &tmp_cerr, sizeof(cerr));
    memcpy(&clog, &tmp_clog, sizeof(clog));
    cin.tie(&cout);
    cerr.flags(ios_base::unitbuf);
 
#ifdef _GLIBCPP_USE_WCHAR_T
    memcpy(&wcout, &tmp_wcout, sizeof(wcout));
    memcpy(&wcin, &tmp_wcin, sizeof(wcin));
    memcpy(&wcerr, &tmp_wcerr, sizeof(wcerr));
    memcpy(&wclog, &tmp_wclog, sizeof(wclog));
    wcin.tie(&wcout);
    wcerr.flags(ios_base::unitbuf);
#endif
  }

-- 
Carlo Wood <carlo@alinoe.com>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]