aboutsummaryrefslogtreecommitdiff
path: root/gold/fileread.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2008-07-25 04:25:49 +0000
committerIan Lance Taylor <ian@airs.com>2008-07-25 04:25:49 +0000
commit2a00e4fb8e170de97cb80a0140ba4d42a8ffd42f (patch)
treebd6483e0ea6e9704286a6ff02d732a79c29e91cf /gold/fileread.cc
parente2df110677592d7b096d7ea9a20d695b49555037 (diff)
downloadgdb-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.cc53
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)