X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Fdescriptors.cc;h=c55d45bb0a87467656c71fcd4a0b6a2aa56cb0fa;hb=bfcf0ccd0131621213c5d6f2908cd703a90176f7;hp=b05bdf1a89d1031d9e7313bd41f5e5281662b952;hpb=604399204f1a6e09056023af6d315dc25e8c6963;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/descriptors.cc b/gold/descriptors.cc index b05bdf1a89..c55d45bb0a 100644 --- a/gold/descriptors.cc +++ b/gold/descriptors.cc @@ -1,6 +1,6 @@ // descriptors.cc -- manage file descriptors for gold -// Copyright 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2008-2015 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -23,24 +23,36 @@ #include "gold.h" #include +#include #include #include #include +#include "debug.h" #include "parameters.h" #include "options.h" #include "gold-threads.h" #include "descriptors.h" +#include "binary-io.h" + +// O_CLOEXEC is only available on newer systems. +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif // Very old systems may not define FD_CLOEXEC. #ifndef FD_CLOEXEC #define FD_CLOEXEC 1 #endif -// O_CLOEXEC is only available on newer systems. -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 +static inline void +set_close_on_exec(int fd ATTRIBUTE_UNUSED) +{ +// Mingw does not define F_SETFD. +#ifdef F_SETFD + fcntl(fd, F_SETFD, FD_CLOEXEC); #endif +} namespace gold { @@ -51,8 +63,8 @@ namespace gold // adjusted downward if we run out of file descriptors. Descriptors::Descriptors() - : lock_(NULL), open_descriptors_(), stack_top_(-1), current_(0), - limit_(8192 - 16) + : lock_(NULL), initialize_lock_(&this->lock_), open_descriptors_(), + stack_top_(-1), current_(0), limit_(8192 - 16) { this->open_descriptors_.reserve(128); } @@ -66,13 +78,12 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) // initialize a Lock until we have parsed the options to find out // whether we are running with threads. We can be called before // options are valid when reading a linker script. - if (this->lock_ == NULL) - { - if (parameters->options_valid()) - this->lock_ = new Lock(); - else - gold_assert(descriptor < 0); - } + bool lock_initialized = this->initialize_lock_.initialize(); + + gold_assert(lock_initialized || descriptor < 0); + + if (is_debugging_enabled(DEBUG_FILES)) + this->limit_ = 8; if (descriptor >= 0) { @@ -92,6 +103,8 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) pod->stack_next = -1; pod->is_on_stack = false; } + gold_debug(DEBUG_FILES, "Reused existing descriptor %d for \"%s\"", + descriptor, name); return descriptor; } } @@ -102,6 +115,9 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) // require callers to pass it. flags |= O_CLOEXEC; + // Always open the file as a binary file. + flags |= O_BINARY; + int new_descriptor = ::open(name, flags, mode); if (new_descriptor < 0 && errno != ENFILE @@ -112,13 +128,14 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) { Hold_lock hl(*this->lock_); - gold_error(_("file %s was removed during the link"), - this->open_descriptors_[descriptor].name); + gold_error(_("file %s was removed during the link"), name); } errno = ENOENT; } + gold_debug(DEBUG_FILES, "Opened new descriptor %d for \"%s\"", + new_descriptor, name); return new_descriptor; } @@ -133,7 +150,7 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) if (O_CLOEXEC == 0 && parameters->options_valid() && parameters->options().has_plugins()) - fcntl(new_descriptor, F_SETFD, FD_CLOEXEC); + set_close_on_exec(new_descriptor); { Hold_optional_lock hl(this->lock_); @@ -153,6 +170,8 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode) if (this->current_ >= this->limit_) this->close_some_descriptor(); + gold_debug(DEBUG_FILES, "Opened new descriptor %d for \"%s\"", + new_descriptor, name); return new_descriptor; } } @@ -200,6 +219,9 @@ Descriptors::release(int descriptor, bool permanent) pod->is_on_stack = true; } } + + gold_debug(DEBUG_FILES, "Released descriptor %d for \"%s\"", + descriptor, pod->name); } // Close some descriptor. The lock is held when this is called. We @@ -224,6 +246,8 @@ Descriptors::close_some_descriptor() if (::close(i) < 0) gold_warning(_("while closing %s: %s"), pod->name, strerror(errno)); --this->current_; + gold_debug(DEBUG_FILES, "Closed descriptor %d for \"%s\"", + i, pod->name); pod->name = NULL; if (last < 0) this->stack_top_ = pod->stack_next; @@ -242,6 +266,30 @@ Descriptors::close_some_descriptor() return false; } +// Close all the descriptors open for reading. + +void +Descriptors::close_all() +{ + Hold_optional_lock hl(this->lock_); + + for (size_t i = 0; i < this->open_descriptors_.size(); i++) + { + Open_descriptor* pod = &this->open_descriptors_[i]; + if (pod->name != NULL && !pod->inuse && !pod->is_write) + { + if (::close(i) < 0) + gold_warning(_("while closing %s: %s"), pod->name, strerror(errno)); + gold_debug(DEBUG_FILES, "Closed descriptor %d for \"%s\" (close_all)", + static_cast(i), pod->name); + pod->name = NULL; + pod->stack_next = -1; + pod->is_on_stack = false; + } + } + this->stack_top_ = -1; +} + // The single global variable which manages descriptors. Descriptors descriptors;