diff options
author | Ian Lance Taylor <ian@airs.com> | 2008-07-25 04:25:49 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2008-07-25 04:25:49 +0000 |
commit | 2a00e4fb8e170de97cb80a0140ba4d42a8ffd42f (patch) | |
tree | bd6483e0ea6e9704286a6ff02d732a79c29e91cf /gold/fileread.cc | |
parent | e2df110677592d7b096d7ea9a20d695b49555037 (diff) | |
download | gdb-2a00e4fb8e170de97cb80a0140ba4d42a8ffd42f.zip gdb-2a00e4fb8e170de97cb80a0140ba4d42a8ffd42f.tar.gz gdb-2a00e4fb8e170de97cb80a0140ba4d42a8ffd42f.tar.bz2 |
PR 5990
* descriptors.cc: New file.
* descriptors.h: New file.
* gold-threads.h (class Hold_optional_lock): New class.
* fileread.cc: Include "descriptors.h".
(File_read::~File_read): Release descriptor rather than closing
it.
(File_read::open) [file]: Call open_descriptor rather than open.
Set is_descriptor_opened_.
(File_read::open) [memory]: Assert that descriptor is not open.
(File_read::reopen_descriptor): New function.
(File_read::release): Release descriptor.
(File_read::do_read): Make non-const. Reopen descriptor.
(File_read::read): Make non-const.
(File_read::make_view): Reopen descriptor.
(File_read::do_readv): Likewise.
* fileread.h (class File_read): Add is_descriptor_opened_ field.
Update declarations.
* layout.cc: Include "descriptors.h".
(Layout::create_build_id): Use open_descriptor rather than open.
* output.cc: Include "descriptors.h".
(Output_file::open): Use open_descriptor rather than open.
* archive.cc (Archive::const_iterator): Change Archive to be
non-const.
(Archive::begin, Archive::end): Make non-const.
(Archive::count_members): Likewise.
* archive.h (class Archive): Update declarations.
* object.h (Object::read): Make non-const.
* Makefile.am (CCFILES): Add descriptors.cc.
(HFILES): Add descriptors.h.
* Makefile.in: Rebuild.
Diffstat (limited to 'gold/fileread.cc')
-rw-r--r-- | gold/fileread.cc | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/gold/fileread.cc b/gold/fileread.cc index cfe0ee6..e476194 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -36,6 +36,7 @@ #include "dirsearch.h" #include "target.h" #include "binary.h" +#include "descriptors.h" #include "fileread.h" namespace gold @@ -83,18 +84,14 @@ unsigned long long File_read::total_mapped_bytes; unsigned long long File_read::current_mapped_bytes; unsigned long long File_read::maximum_mapped_bytes; -// The File_read class is designed to support file descriptor caching, -// but this is not currently implemented. - File_read::~File_read() { gold_assert(this->token_.is_writable()); - if (this->descriptor_ >= 0) + if (this->is_descriptor_opened_) { - if (close(this->descriptor_) < 0) - gold_warning(_("close of %s failed: %s"), - this->name_.c_str(), strerror(errno)); + release_descriptor(this->descriptor_, true); this->descriptor_ = -1; + this->is_descriptor_opened_ = false; } this->name_.clear(); this->clear_views(true); @@ -107,13 +104,16 @@ File_read::open(const Task* task, const std::string& name) { gold_assert(this->token_.is_writable() && this->descriptor_ < 0 + && !this->is_descriptor_opened_ && this->name_.empty()); this->name_ = name; - this->descriptor_ = ::open(this->name_.c_str(), O_RDONLY); + this->descriptor_ = open_descriptor(-1, this->name_.c_str(), + O_RDONLY); if (this->descriptor_ >= 0) { + this->is_descriptor_opened_ = true; struct stat s; if (::fstat(this->descriptor_, &s) < 0) gold_error(_("%s: fstat failed: %s"), @@ -136,6 +136,7 @@ File_read::open(const Task* task, const std::string& name, { gold_assert(this->token_.is_writable() && this->descriptor_ < 0 + && !this->is_descriptor_opened_ && this->name_.empty()); this->name_ = name; this->contents_ = contents; @@ -144,6 +145,22 @@ File_read::open(const Task* task, const std::string& name, return true; } +// Reopen a descriptor if necessary. + +void +File_read::reopen_descriptor() +{ + if (!this->is_descriptor_opened_) + { + this->descriptor_ = open_descriptor(this->descriptor_, + this->name_.c_str(), + O_RDONLY); + if (this->descriptor_ < 0) + gold_fatal(_("could not reopen file %s"), this->name_.c_str()); + this->is_descriptor_opened_ = true; + } +} + // Release the file. This is called when we are done with the file in // a Task. @@ -159,9 +176,17 @@ File_read::release() File_read::maximum_mapped_bytes = File_read::current_mapped_bytes; // Only clear views if there is only one attached object. Otherwise - // we waste time trying to clear cached archive views. + // we waste time trying to clear cached archive views. Similarly + // for releasing the descriptor. if (this->object_count_ <= 1) - this->clear_views(false); + { + this->clear_views(false); + if (this->is_descriptor_opened_) + { + release_descriptor(this->descriptor_, false); + this->is_descriptor_opened_ = false; + } + } this->released_ = true; } @@ -243,7 +268,7 @@ File_read::find_view(off_t start, section_size_type size, // the buffer at P. void -File_read::do_read(off_t start, section_size_type size, void* p) const +File_read::do_read(off_t start, section_size_type size, void* p) { ssize_t bytes; if (this->contents_ != NULL) @@ -257,6 +282,7 @@ File_read::do_read(off_t start, section_size_type size, void* p) const } else { + this->reopen_descriptor(); bytes = ::pread(this->descriptor_, p, size, start); if (static_cast<section_size_type>(bytes) == size) return; @@ -279,7 +305,7 @@ File_read::do_read(off_t start, section_size_type size, void* p) const // Read data from the file. void -File_read::read(off_t start, section_size_type size, void* p) const +File_read::read(off_t start, section_size_type size, void* p) { const File_read::View* pv = this->find_view(start, size, -1U, NULL); if (pv != NULL) @@ -349,6 +375,7 @@ File_read::make_view(off_t start, section_size_type size, } else { + this->reopen_descriptor(); void* p = ::mmap(NULL, psize, PROT_READ, MAP_PRIVATE, this->descriptor_, poff); if (p == MAP_FAILED) @@ -493,6 +520,8 @@ File_read::do_readv(off_t base, const Read_multiple& rm, size_t start, last_offset = i_entry.file_offset + i_entry.size; } + this->reopen_descriptor(); + gold_assert(iov_index < sizeof iov / sizeof iov[0]); if (::lseek(this->descriptor_, base + first_offset, SEEK_SET) < 0) |