diff --git a/panda/src/downloader/extractor.cxx b/panda/src/downloader/extractor.cxx index 50e48e8760..1de3bdb64e 100644 --- a/panda/src/downloader/extractor.cxx +++ b/panda/src/downloader/extractor.cxx @@ -78,7 +78,7 @@ void Extractor:: reset() { if (_initiated) { if (_read != (istream *)NULL) { - delete _read; + Multifile::close_read_subfile(_read); _read = (istream *)NULL; } _write.close(); @@ -204,7 +204,7 @@ step() { downloader_cat.debug() << "Finished current subfile.\n"; } - delete _read; + Multifile::close_read_subfile(_read); _read = (istream *)NULL; _write.close(); _request_index++; diff --git a/panda/src/express/multifile.cxx b/panda/src/express/multifile.cxx index 21d054b2aa..863fb8bca5 100644 --- a/panda/src/express/multifile.cxx +++ b/panda/src/express/multifile.cxx @@ -1072,8 +1072,9 @@ get_subfile_internal_length(int index) const { // subfile. // // The returned istream will have been allocated via -// new; you should delete it when you are finished -// reading the subfile. +// new; you should pass the pointer to +// close_read_subfile() when you are finished with it to +// delete it and release its resources. // // Any future calls to repack() or close() (or the // Multifile destructor) will invalidate all currently @@ -1156,6 +1157,31 @@ open_read_subfile(int index) { return stream; } +//////////////////////////////////////////////////////////////////// +// Function: Multifile::close_read_subfile +// Access: Published, Static +// Description: Closes a file opened by a previous call to +// open_read_subfile(). This really just deletes the +// istream pointer, but it is recommended to use this +// interface instead of deleting it explicitly, to help +// work around compiler issues. +//////////////////////////////////////////////////////////////////// +void Multifile:: +close_read_subfile(istream *stream) { + if (stream != (istream *)NULL) { + // For some reason--compiler bug in gcc 3.2?--explicitly deleting + // the stream pointer does not call the appropriate global delete + // function; instead apparently calling the system delete + // function. So we call the delete function by hand instead. +#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) + stream->~istream(); + (*global_operator_delete)(stream); +#else + delete stream; +#endif + } +} + //////////////////////////////////////////////////////////////////// // Function: Multifile::extract_subfile // Access: Published @@ -1207,7 +1233,7 @@ extract_subfile_to(int index, ostream &out) { } bool failed = (in->fail() && !in->eof()); - delete in; + close_read_subfile(in); nassertr(!failed, false); return (!out.fail()); @@ -1251,7 +1277,7 @@ compare_subfile(int index, const Filename &filename) { if (file_size != (streampos)get_subfile_length(index)) { // The files have different sizes. - delete in1; + close_read_subfile(in1); return false; } @@ -1261,8 +1287,8 @@ compare_subfile(int index, const Filename &filename) { int byte2 = in2.get(); while (!in1->fail() && !in1->eof() && !in2.fail() && !in2.eof()) { - if (byte1 != byte2) { - delete in1; + if (byte1 != byte2) { + close_read_subfile(in1); return false; } byte1 = in1->get(); @@ -1270,7 +1296,7 @@ compare_subfile(int index, const Filename &filename) { } bool failed = (in1->fail() && !in1->eof()) || (in2.fail() && !in2.eof()); - delete in1; + close_read_subfile(in1); nassertr(!failed, false); @@ -1354,7 +1380,7 @@ read_subfile(int index, pvector &result) { } bool failed = in->fail() && !in->eof(); - delete in; + close_read_subfile(in); nassertr(!failed, false); return true; } diff --git a/panda/src/express/multifile.h b/panda/src/express/multifile.h index 550107c64c..d1ebfbd77c 100644 --- a/panda/src/express/multifile.h +++ b/panda/src/express/multifile.h @@ -104,6 +104,7 @@ PUBLISHED: BLOCKING INLINE string read_subfile(int index); BLOCKING istream *open_read_subfile(int index); + BLOCKING static void close_read_subfile(istream *stream); BLOCKING bool extract_subfile(int index, const Filename &filename); BLOCKING bool extract_subfile_to(int index, ostream &out); BLOCKING bool compare_subfile(int index, const Filename &filename); diff --git a/panda/src/express/virtualFileMountMultifile.cxx b/panda/src/express/virtualFileMountMultifile.cxx index d5078d7738..71f4498781 100644 --- a/panda/src/express/virtualFileMountMultifile.cxx +++ b/panda/src/express/virtualFileMountMultifile.cxx @@ -77,6 +77,11 @@ open_read_file(const Filename &file) const { if (subfile_index < 0) { return NULL; } + + // The caller will eventually pass this pointer to + // VirtualFileSystem::close_read_file(), not to + // Multifile::close_read_subfile(). Fortunately, these two methods + // do the same thing, so that doesn't matter. return _multifile->open_read_subfile(subfile_index); }