aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-07-16 23:22:14 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-07-16 23:22:14 +0000
commite35be9c529c32f636b376b248cb6395ae8d0f798 (patch)
tree715610bdb10abd7f577cbfbf0163fcbf029a3bca
parentfb83da0d4cc49e419644d4f6916df94b36f784c6 (diff)
downloadpaludis-e35be9c529c32f636b376b248cb6395ae8d0f798.tar.gz
paludis-e35be9c529c32f636b376b248cb6395ae8d0f798.tar.xz
Be thread safe.
-rw-r--r--paludis/dep_list/uninstall_list.cc6
-rw-r--r--paludis/dep_spec.cc5
-rw-r--r--paludis/dep_spec_flattener.cc2
-rw-r--r--paludis/dep_spec_pretty_printer.cc6
-rw-r--r--paludis/dep_spec_pretty_printer.hh4
-rw-r--r--paludis/dep_tag.cc5
-rw-r--r--paludis/distribution.cc1
-rw-r--r--paludis/environment_implementation.cc7
-rw-r--r--paludis/environments/paludis/keywords_conf.cc4
-rw-r--r--paludis/environments/paludis/licenses_conf.cc3
-rw-r--r--paludis/environments/paludis/paludis_config.cc12
-rw-r--r--paludis/environments/paludis/paludis_environment.cc8
-rw-r--r--paludis/environments/paludis/use_conf.cc34
-rw-r--r--paludis/environments/portage/portage_environment.cc6
-rw-r--r--paludis/hooker.cc4
-rw-r--r--paludis/package_database.cc8
-rw-r--r--paludis/portage_dep_parser.cc6
-rw-r--r--paludis/repositories/e/e_key.cc21
-rw-r--r--paludis/repositories/e/e_repository.cc25
-rw-r--r--paludis/repositories/e/e_repository_news.cc6
-rw-r--r--paludis/repositories/e/ebuild_entries.cc2
-rw-r--r--paludis/repositories/e/ebuild_id.cc21
-rw-r--r--paludis/repositories/e/eclass_mtimes.cc4
-rw-r--r--paludis/repositories/e/exheres_layout.cc19
-rw-r--r--paludis/repositories/e/traditional_layout.cc19
-rw-r--r--paludis/repositories/e/vdb_id.cc9
-rw-r--r--paludis/repositories/e/vdb_repository.cc41
-rw-r--r--paludis/repositories/fake/fake_package_id.cc5
-rw-r--r--paludis/repositories/gems/gem_specification.cc5
-rw-r--r--paludis/repositories/gems/gems_repository.cc19
-rw-r--r--paludis/repositories/gems/installed_gems_repository.cc21
-rw-r--r--paludis/repositories/gems/yaml.cc13
-rw-r--r--paludis/repositories/virtuals/installed_virtuals_repository.cc4
-rw-r--r--paludis/repositories/virtuals/package_id.cc4
-rw-r--r--paludis/repositories/virtuals/virtuals_repository.cc7
-rw-r--r--paludis/repository_name_cache.cc7
-rw-r--r--paludis/set_file.cc21
-rw-r--r--paludis/util/fs_entry.cc279
-rw-r--r--paludis/util/fs_entry.hh15
-rw-r--r--paludis/version_spec.cc7
40 files changed, 514 insertions, 181 deletions
diff --git a/paludis/dep_list/uninstall_list.cc b/paludis/dep_list/uninstall_list.cc
index 8208a4a..f01163c 100644
--- a/paludis/dep_list/uninstall_list.cc
+++ b/paludis/dep_list/uninstall_list.cc
@@ -28,6 +28,7 @@
#include <paludis/util/set-impl.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/hashed_containers.hh>
#include <paludis/match_package.hh>
#include <paludis/package_database.hh>
@@ -58,6 +59,7 @@ namespace paludis
UninstallListOptions options;
std::list<UninstallListEntry> uninstall_list;
+ mutable Mutex dep_collector_cache_mutex;
mutable DepCollectorCache dep_collector_cache;
Implementation(const Environment * const e, const UninstallListOptions & o) :
@@ -312,6 +314,7 @@ UninstallList::collect_depped_upon(tr1::shared_ptr<const PackageIDSet> targets)
tr1::shared_ptr<PackageIDSet> result(new PackageIDSet);
+ Lock l(_imp->dep_collector_cache_mutex);
for (PackageIDSet::Iterator i(targets->begin()), i_end(targets->end()) ;
i != i_end ; ++i)
{
@@ -409,6 +412,9 @@ UninstallList::add_dependencies(const PackageID & e, const bool error)
Context context("When adding things that depend upon '" + stringify(e) + "':");
tr1::shared_ptr<const PackageIDSet> everything(collect_all_installed());
+
+ Lock l(_imp->dep_collector_cache_mutex);
+
for (PackageIDSet::Iterator i(everything->begin()),
i_end(everything->end()) ; i != i_end ; ++i)
{
diff --git a/paludis/dep_spec.cc b/paludis/dep_spec.cc
index bc2c30a..6c9b79b 100644
--- a/paludis/dep_spec.cc
+++ b/paludis/dep_spec.cc
@@ -27,6 +27,7 @@
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/stringify.hh>
+#include <paludis/util/mutex.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
#include <list>
@@ -124,6 +125,8 @@ namespace paludis
template<>
struct Implementation<PackageDepSpec>
{
+ Mutex mutex;
+
bool unique;
tr1::shared_ptr<QualifiedPackageName> package_ptr;
@@ -939,6 +942,8 @@ PackageDepSpec::set_tag(const tr1::shared_ptr<const DepTag> & s)
void
PackageDepSpec::_make_unique()
{
+ Lock l(_imp->mutex);
+
if (_imp->unique)
return;
diff --git a/paludis/dep_spec_flattener.cc b/paludis/dep_spec_flattener.cc
index 20fe76d..8f7916a 100644
--- a/paludis/dep_spec_flattener.cc
+++ b/paludis/dep_spec_flattener.cc
@@ -48,7 +48,7 @@ namespace paludis
const tr1::shared_ptr<const PackageID> pkg;
- mutable std::list<tr1::shared_ptr<const StringDepSpec > > specs;
+ std::list<tr1::shared_ptr<const StringDepSpec > > specs;
Implementation(const Environment * const e,
const tr1::shared_ptr<const PackageID> p) :
diff --git a/paludis/dep_spec_pretty_printer.cc b/paludis/dep_spec_pretty_printer.cc
index 1c3c242..496c588 100644
--- a/paludis/dep_spec_pretty_printer.cc
+++ b/paludis/dep_spec_pretty_printer.cc
@@ -43,7 +43,7 @@ namespace paludis
unsigned indent;
bool use_newlines;
bool outer_block;
- mutable bool need_space;
+ bool need_space;
Implementation(unsigned i, bool b) :
indent(i),
@@ -162,7 +162,7 @@ DepSpecPrettyPrinter::visit_leaf(const BlockDepSpec & b)
}
std::string
-DepSpecPrettyPrinter::newline() const
+DepSpecPrettyPrinter::newline()
{
if (_imp->use_newlines)
return "\n";
@@ -174,7 +174,7 @@ DepSpecPrettyPrinter::newline() const
}
std::string
-DepSpecPrettyPrinter::indent() const
+DepSpecPrettyPrinter::indent()
{
if (_imp->use_newlines)
return std::string(_imp->indent, ' ');
diff --git a/paludis/dep_spec_pretty_printer.hh b/paludis/dep_spec_pretty_printer.hh
index a422eaa..3024329 100644
--- a/paludis/dep_spec_pretty_printer.hh
+++ b/paludis/dep_spec_pretty_printer.hh
@@ -43,8 +43,8 @@ namespace paludis
friend std::ostream & operator<< (std::ostream &, const DepSpecPrettyPrinter &);
private:
- std::string newline() const;
- std::string indent() const;
+ std::string newline();
+ std::string indent();
public:
///\name Basic operations
diff --git a/paludis/dep_tag.cc b/paludis/dep_tag.cc
index 4e7172a..65bf577 100644
--- a/paludis/dep_tag.cc
+++ b/paludis/dep_tag.cc
@@ -25,6 +25,7 @@
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/instantiation_policy-impl.hh>
#include <paludis/util/set-impl.hh>
+#include <paludis/util/mutex.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
/** \file
@@ -274,6 +275,7 @@ namespace paludis
template <>
struct Implementation<DependencyDepTag>
{
+ mutable Mutex mutex;
mutable std::string str;
tr1::shared_ptr<const PackageID> id;
@@ -304,6 +306,8 @@ DependencyDepTag::~DependencyDepTag()
std::string
DependencyDepTag::full_text() const
{
+ Lock l(_imp->mutex);
+
if (_imp->str.empty())
{
_imp->str.append(stringify(*_imp->id));
@@ -314,6 +318,7 @@ DependencyDepTag::full_text() const
_imp->cond->accept(pretty);
_imp->str.append(stringify(pretty));
}
+
return _imp->str;
}
diff --git a/paludis/distribution.cc b/paludis/distribution.cc
index 4ccb2eb..0f711f1 100644
--- a/paludis/distribution.cc
+++ b/paludis/distribution.cc
@@ -47,7 +47,6 @@ namespace paludis
struct Implementation<DistributionData>
{
MakeHashedMap<std::string, tr1::shared_ptr<const Distribution> >::Type values;
- mutable tr1::shared_ptr<const Distribution> default_distribution;
Implementation()
{
diff --git a/paludis/environment_implementation.cc b/paludis/environment_implementation.cc
index 9e0fbc9..d0dfc95 100644
--- a/paludis/environment_implementation.cc
+++ b/paludis/environment_implementation.cc
@@ -25,6 +25,7 @@
#include <paludis/util/log.hh>
#include <paludis/util/save.hh>
#include <paludis/util/set.hh>
+#include <paludis/util/make_shared_ptr.hh>
#include <paludis/eapi.hh>
#include <paludis/hook.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
@@ -42,8 +43,7 @@ EnvironmentImplementation::~EnvironmentImplementation()
tr1::shared_ptr<const FSEntrySequence>
EnvironmentImplementation::bashrc_files() const
{
- static tr1::shared_ptr<const FSEntrySequence> result(new FSEntrySequence);
- return result;
+ return make_shared_ptr(new FSEntrySequence);
}
tr1::shared_ptr<const FSEntrySequence>
@@ -167,8 +167,7 @@ EnvironmentImplementation::default_distribution() const
tr1::shared_ptr<const SetNameSet>
EnvironmentImplementation::set_names() const
{
- static tr1::shared_ptr<const SetNameSet> result(new SetNameSet);
- return result;
+ return make_shared_ptr(new SetNameSet);
}
bool
diff --git a/paludis/environments/paludis/keywords_conf.cc b/paludis/environments/paludis/keywords_conf.cc
index d2030cf..ea596fe 100644
--- a/paludis/environments/paludis/keywords_conf.cc
+++ b/paludis/environments/paludis/keywords_conf.cc
@@ -30,6 +30,7 @@
#include <paludis/util/log.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/tokeniser.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/set.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
@@ -58,6 +59,7 @@ namespace paludis
SpecificMap qualified;
UnspecificMap unqualified;
mutable NamedSetMap set;
+ mutable Mutex set_mutex;
Implementation(const PaludisEnvironment * const e) :
env(e)
@@ -171,6 +173,8 @@ KeywordsConf::query(tr1::shared_ptr<const KeywordNameSet> k, const PackageID & e
/* next: named sets */
{
+ Lock lock(_imp->set_mutex);
+
for (NamedSetMap::iterator i(_imp->set.begin()), i_end(_imp->set.end()) ;
i != i_end ; ++i)
{
diff --git a/paludis/environments/paludis/licenses_conf.cc b/paludis/environments/paludis/licenses_conf.cc
index fde833d..0e1144f 100644
--- a/paludis/environments/paludis/licenses_conf.cc
+++ b/paludis/environments/paludis/licenses_conf.cc
@@ -30,6 +30,7 @@
#include <paludis/util/log.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/mutex.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <list>
#include <vector>
@@ -56,6 +57,7 @@ namespace paludis
SpecificMap qualified;
UnspecificMap unqualified;
mutable NamedSetMap set;
+ mutable Mutex set_mutex;
Implementation(const PaludisEnvironment * const e) :
env(e)
@@ -163,6 +165,7 @@ LicensesConf::query(const std::string & t, const PackageID & e) const
/* next: named sets */
{
+ Lock lock(_imp->set_mutex);
for (NamedSetMap::iterator i(_imp->set.begin()), i_end(_imp->set.end()) ;
i != i_end ; ++i)
{
diff --git a/paludis/environments/paludis/paludis_config.cc b/paludis/environments/paludis/paludis_config.cc
index eafa232..b5595fd 100644
--- a/paludis/environments/paludis/paludis_config.cc
+++ b/paludis/environments/paludis/paludis_config.cc
@@ -42,6 +42,7 @@
#include <paludis/util/system.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/tr1_functional.hh>
#include <fstream>
@@ -87,6 +88,7 @@ namespace paludis
std::string paludis_command;
std::string root;
std::string config_dir;
+ mutable Mutex distribution_mutex;
mutable std::string distribution;
tr1::shared_ptr<FSEntrySequence> bashrc_files;
@@ -99,9 +101,11 @@ namespace paludis
tr1::shared_ptr<PackageMaskConf> package_unmask_conf;
tr1::shared_ptr<MirrorsConf> mirrors_conf;
+ mutable Mutex reduced_mutex;
mutable tr1::shared_ptr<uid_t> reduced_uid;
mutable tr1::shared_ptr<gid_t> reduced_gid;
+ mutable Mutex environment_conf_mutex;
mutable bool has_environment_conf;
mutable bool accept_breaks_portage;
mutable std::string reduced_username;
@@ -131,6 +135,8 @@ namespace paludis
void
Implementation<PaludisConfig>::need_environment_conf() const
{
+ Lock lock(environment_conf_mutex);
+
if (has_environment_conf)
return;
@@ -579,6 +585,8 @@ PaludisConfig::config_dir() const
uid_t
PaludisConfig::reduced_uid() const
{
+ Lock lock(_imp->reduced_mutex);
+
if (! _imp->reduced_uid)
{
Context context("When determining reduced UID:");
@@ -608,6 +616,8 @@ PaludisConfig::reduced_uid() const
gid_t
PaludisConfig::reduced_gid() const
{
+ Lock lock(_imp->reduced_mutex);
+
if (! _imp->reduced_gid)
{
if (0 != getuid())
@@ -688,6 +698,8 @@ PaludisConfig::mirrors_conf() const
std::string
PaludisConfig::distribution() const
{
+ Lock lock(_imp->distribution_mutex);
+
if (! _imp->distribution.empty())
return _imp->distribution;
diff --git a/paludis/environments/paludis/paludis_environment.cc b/paludis/environments/paludis/paludis_environment.cc
index d560f5e..3363635 100644
--- a/paludis/environments/paludis/paludis_environment.cc
+++ b/paludis/environments/paludis/paludis_environment.cc
@@ -47,6 +47,7 @@
#include <paludis/util/tr1_functional.hh>
#include <paludis/util/set.hh>
#include <paludis/util/sequence.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/map.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
@@ -62,6 +63,7 @@ namespace paludis
template<>
struct Implementation<PaludisEnvironment>
{
+ mutable Mutex hook_mutex;
mutable bool done_hooks;
mutable tr1::shared_ptr<Hooker> hooker;
mutable std::list<std::pair<FSEntry, bool> > hook_dirs;
@@ -161,7 +163,7 @@ PaludisEnvironment::query_use(const UseFlagName & f, const PackageID & e) const
Context context("When querying use flag '" + stringify(f) + "' for '" + stringify(e) +
"' in Paludis environment:");
- static bool recursive(false);
+ PALUDIS_TLS bool recursive(false);
if (recursive)
{
Log::get_instance()->message(ll_warning, lc_context) <<
@@ -268,6 +270,8 @@ PaludisEnvironment::set_paludis_command(const std::string & s)
HookResult
PaludisEnvironment::perform_hook(const Hook & hook) const
{
+ Lock lock(_imp->hook_mutex);
+
if (! _imp->hooker)
{
_imp->need_hook_dirs(_imp->config->config_dir());
@@ -283,6 +287,8 @@ PaludisEnvironment::perform_hook(const Hook & hook) const
tr1::shared_ptr<const FSEntrySequence>
PaludisEnvironment::hook_dirs() const
{
+ Lock lock(_imp->hook_mutex);
+
_imp->need_hook_dirs(_imp->config->config_dir());
tr1::shared_ptr<FSEntrySequence> result(new FSEntrySequence);
diff --git a/paludis/environments/paludis/use_conf.cc b/paludis/environments/paludis/use_conf.cc
index 24197df..4193fc1 100644
--- a/paludis/environments/paludis/use_conf.cc
+++ b/paludis/environments/paludis/use_conf.cc
@@ -33,6 +33,7 @@
#include <paludis/util/iterator.hh>
#include <paludis/util/strip.hh>
#include <paludis/util/set.hh>
+#include <paludis/util/mutex.hh>
#include <list>
#include <vector>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
@@ -59,6 +60,7 @@ namespace paludis
const PaludisEnvironment * const env;
Qualified qualified;
Unqualified unqualified;
+ mutable Mutex set_mutex;
mutable Sets sets;
Implementation(const PaludisEnvironment * const e) :
@@ -244,6 +246,7 @@ UseConf::query(const UseFlagName & f, const PackageID & e) const
/* next: named sets */
for (Sets::iterator r(_imp->sets.begin()), r_end(_imp->sets.end()) ; r != r_end ; ++r)
{
+ Lock lock(_imp->set_mutex);
if (! r->second.first)
{
r->second.first = _imp->env->set(r->first);
@@ -333,27 +336,30 @@ UseConf::known_use_expand_names(const UseFlagName & prefix, const PackageID & e)
result->insert(i->first);
}
- for (Sets::iterator r(_imp->sets.begin()), r_end(_imp->sets.end()) ; r != r_end ; ++r)
{
- if (! r->second.first)
+ Lock lock(_imp->set_mutex);
+ for (Sets::iterator r(_imp->sets.begin()), r_end(_imp->sets.end()) ; r != r_end ; ++r)
{
- r->second.first = _imp->env->set(r->first);
if (! r->second.first)
{
- Log::get_instance()->message(ll_warning, lc_no_context) << "Set name '"
- << r->first << "' does not exist";
- r->second.first.reset(new ConstTreeSequence<SetSpecTree, AllDepSpec>(
- tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
+ r->second.first = _imp->env->set(r->first);
+ if (! r->second.first)
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context) << "Set name '"
+ << r->first << "' does not exist";
+ r->second.first.reset(new ConstTreeSequence<SetSpecTree, AllDepSpec>(
+ tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
+ }
}
- }
- if (! match_package_in_set(*_imp->env, *r->second.first, e))
- continue;
+ if (! match_package_in_set(*_imp->env, *r->second.first, e))
+ continue;
- for (UseFlagWithStateMap::const_iterator i(r->second.second.first.begin()), i_end(r->second.second.first.end()) ;
- i != i_end ; ++i)
- if (0 == i->first.data().compare(0, prefix_lower.length(), prefix_lower))
- result->insert(i->first);
+ for (UseFlagWithStateMap::const_iterator i(r->second.second.first.begin()), i_end(r->second.second.first.end()) ;
+ i != i_end ; ++i)
+ if (0 == i->first.data().compare(0, prefix_lower.length(), prefix_lower))
+ result->insert(i->first);
+ }
}
for (Unqualified::const_iterator p(_imp->unqualified.begin()), p_end(_imp->unqualified.end()) ; p != p_end ; ++p)
diff --git a/paludis/environments/portage/portage_environment.cc b/paludis/environments/portage/portage_environment.cc
index 9f8c2b6..a943a43 100644
--- a/paludis/environments/portage/portage_environment.cc
+++ b/paludis/environments/portage/portage_environment.cc
@@ -41,6 +41,7 @@
#include <paludis/package_id.hh>
#include <algorithm>
#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/mutex.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
#include <functional>
@@ -82,6 +83,7 @@ namespace paludis
PackageMask package_mask;
PackageUnmask package_unmask;
+ mutable Mutex hook_mutex;
mutable bool done_hooks;
mutable tr1::shared_ptr<Hooker> hooker;
mutable std::list<FSEntry> hook_dirs;
@@ -433,7 +435,7 @@ PortageEnvironment::query_use(const UseFlagName & f, const PackageID & e) const
Context context("When querying use flag '" + stringify(f) + "' for '" + stringify(e) +
"' in Portage environment:");
- static bool recursive(false);
+ PALUDIS_TLS bool recursive(false);
if (recursive)
{
Log::get_instance()->message(ll_warning, lc_context) <<
@@ -599,6 +601,7 @@ PortageEnvironment::perform_hook(const Hook & hook) const
{
using namespace tr1::placeholders;
+ Lock l(_imp->hook_mutex);
if (! _imp->hooker)
{
_imp->need_hook_dirs();
@@ -613,6 +616,7 @@ PortageEnvironment::perform_hook(const Hook & hook) const
tr1::shared_ptr<const FSEntrySequence>
PortageEnvironment::hook_dirs() const
{
+ Lock l(_imp->hook_mutex);
_imp->need_hook_dirs();
tr1::shared_ptr<FSEntrySequence> result(new FSEntrySequence);
std::copy(_imp->hook_dirs.begin(), _imp->hook_dirs.end(), result->back_inserter());
diff --git a/paludis/hooker.cc b/paludis/hooker.cc
index 498999a..90c5350 100644
--- a/paludis/hooker.cc
+++ b/paludis/hooker.cc
@@ -34,6 +34,7 @@
#include <paludis/util/graph-impl.hh>
#include <paludis/util/pstream.hh>
#include <paludis/util/tokeniser.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/about.hh>
#include <list>
#include <iterator>
@@ -361,6 +362,7 @@ namespace paludis
{
const Environment * const env;
std::list<std::pair<FSEntry, bool> > dirs;
+ mutable Mutex hook_files_mutex;
mutable std::map<std::string, std::list<tr1::shared_ptr<HookFile> > > hook_files;
Implementation(const Environment * const e) :
@@ -383,6 +385,7 @@ Hooker::~Hooker()
void
Hooker::add_dir(const FSEntry & dir, const bool v)
{
+ Lock l(_imp->hook_files_mutex);
_imp->hook_files.clear();
_imp->dirs.push_back(std::make_pair(dir, v));
}
@@ -440,6 +443,7 @@ Hooker::perform_hook(const Hook & hook) const
/* file hooks, but only if necessary */
+ Lock l(_imp->hook_files_mutex);
std::map<std::string, std::list<tr1::shared_ptr<HookFile> > >::iterator h(_imp->hook_files.find(hook.name()));
if (h == _imp->hook_files.end())
diff --git a/paludis/package_database.cc b/paludis/package_database.cc
index f79ba42..5e74fe4 100644
--- a/paludis/package_database.cc
+++ b/paludis/package_database.cc
@@ -334,8 +334,9 @@ PackageDatabase::query(const Query & q, const QueryOrder query_order) const
{
/* if someone's bored, they can rewrite this to be a lot faster */
PackageIDComparator c(this);
- std::set<tr1::shared_ptr<const PackageID>, tr1::function<bool (tr1::shared_ptr<const PackageID>, tr1::shared_ptr<const PackageID>)> > s(
- result->begin(), result->end(), tr1::bind(&PackageIDComparator::operator(), tr1::cref(c), _2, _1));
+ std::set<tr1::shared_ptr<const PackageID>, tr1::function<bool (tr1::shared_ptr<const PackageID>,
+ tr1::shared_ptr<const PackageID>)> > s(
+ result->begin(), result->end(), tr1::bind(&PackageIDComparator::operator(), tr1::cref(c), _2, _1));
result.reset(new PackageIDSequence);
while (! s.empty())
@@ -343,7 +344,8 @@ PackageDatabase::query(const Query & q, const QueryOrder query_order) const
result->push_front(*s.begin());
s.erase(s.begin());
- for (std::set<tr1::shared_ptr<const PackageID>, tr1::function<bool (tr1::shared_ptr<const PackageID>, tr1::shared_ptr<const PackageID>)> >::iterator
+ for (std::set<tr1::shared_ptr<const PackageID>, tr1::function<bool (tr1::shared_ptr<const PackageID>,
+ tr1::shared_ptr<const PackageID>)> >::iterator
i(s.begin()) ; i != s.end() ; )
{
if ((*i)->name() == (*result->begin())->name() && (*i)->slot() == (*result->begin())->slot())
diff --git a/paludis/portage_dep_parser.cc b/paludis/portage_dep_parser.cc
index ea7015a..b5a7b8f 100644
--- a/paludis/portage_dep_parser.cc
+++ b/paludis/portage_dep_parser.cc
@@ -210,7 +210,8 @@ namespace
template <typename H_, bool>
struct HandleAny
{
- static void handle(const std::string &, std::stack<std::pair<tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > & stack)
+ static void handle(const std::string &, std::stack<std::pair<tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > &
+ stack)
{
tr1::shared_ptr<ConstTreeSequence<H_, AnyDepSpec> > a(new ConstTreeSequence<H_, AnyDepSpec>(
tr1::shared_ptr<AnyDepSpec>(new AnyDepSpec)));
@@ -307,7 +308,8 @@ PortageDepParser::_parse(const std::string & s, bool disallow_any_use, const I_
tr1::shared_ptr<ConstTreeSequence<H_, AllDepSpec> > a(new ConstTreeSequence<H_, AllDepSpec>(
tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
stack.top().first(a);
- stack.push(std::make_pair(tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>(tr1::bind(&ConstTreeSequence<H_, AllDepSpec>::add, a, _1)), false));
+ stack.push(std::make_pair(tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>(
+ tr1::bind(&ConstTreeSequence<H_, AllDepSpec>::add, a, _1)), false));
state = dps_had_paren;
}
continue;
diff --git a/paludis/repositories/e/e_key.cc b/paludis/repositories/e/e_key.cc
index 8309517..008365a 100644
--- a/paludis/repositories/e/e_key.cc
+++ b/paludis/repositories/e/e_key.cc
@@ -219,6 +219,7 @@ namespace paludis
{
const tr1::shared_ptr<const PackageID> id;
const std::string string_value;
+ mutable Mutex value_mutex;
mutable tr1::shared_ptr<const URISpecTree::ConstItem> value;
Implementation(const tr1::shared_ptr<const PackageID> & i, const std::string & v) :
@@ -244,6 +245,8 @@ EURIKey::~EURIKey()
const tr1::shared_ptr<const URISpecTree::ConstItem>
EURIKey::value() const
{
+ Lock l(_imp->value_mutex);
+
if (_imp->value)
return _imp->value;
@@ -259,6 +262,7 @@ namespace paludis
{
const tr1::shared_ptr<const PackageID> id;
const std::string string_value;
+ mutable Mutex value_mutex;
mutable tr1::shared_ptr<const RestrictSpecTree::ConstItem> value;
Implementation(const tr1::shared_ptr<const PackageID> & i, const std::string & v) :
@@ -284,6 +288,8 @@ ERestrictKey::~ERestrictKey()
const tr1::shared_ptr<const RestrictSpecTree::ConstItem>
ERestrictKey::value() const
{
+ Lock l(_imp->value_mutex);
+
if (_imp->value)
return _imp->value;
@@ -299,6 +305,7 @@ namespace paludis
{
const tr1::shared_ptr<const PackageID> id;
const std::string string_value;
+ mutable Mutex value_mutex;
mutable tr1::shared_ptr<const ProvideSpecTree::ConstItem> value;
Implementation(const tr1::shared_ptr<const PackageID> & i, const std::string & v) :
@@ -324,6 +331,8 @@ EProvideKey::~EProvideKey()
const tr1::shared_ptr<const ProvideSpecTree::ConstItem>
EProvideKey::value() const
{
+ Lock l(_imp->value_mutex);
+
if (_imp->value)
return _imp->value;
@@ -504,6 +513,7 @@ namespace paludis
{
const tr1::shared_ptr<const PackageID> id;
const std::string string_value;
+ mutable Mutex value_mutex;
mutable tr1::shared_ptr<UseFlagNameSet> value;
Implementation(const tr1::shared_ptr<const PackageID> & i, const std::string & v) :
@@ -529,6 +539,8 @@ EUseKey::~EUseKey()
const tr1::shared_ptr<const UseFlagNameSet>
EUseKey::value() const
{
+ Lock l(_imp->value_mutex);
+
if (_imp->value)
return _imp->value;
@@ -550,6 +562,7 @@ namespace paludis
{
const tr1::shared_ptr<const PackageID> id;
const std::string string_value;
+ mutable Mutex value_mutex;
mutable tr1::shared_ptr<InheritedSet> value;
Implementation(const tr1::shared_ptr<const PackageID> & i, const std::string & v) :
@@ -575,6 +588,8 @@ EInheritedKey::~EInheritedKey()
const tr1::shared_ptr<const InheritedSet>
EInheritedKey::value() const
{
+ Lock l(_imp->value_mutex);
+
if (_imp->value)
return _imp->value;
@@ -591,6 +606,7 @@ namespace paludis
{
const tr1::shared_ptr<const PackageID> id;
const FSEntry filename;
+ mutable Mutex value_mutex;
mutable tr1::shared_ptr<Contents> value;
Implementation(const tr1::shared_ptr<const PackageID> & i, const FSEntry & v) :
@@ -616,6 +632,8 @@ EContentsKey::~EContentsKey()
const tr1::shared_ptr<const Contents>
EContentsKey::value() const
{
+ Lock l(_imp->value_mutex);
+
if (_imp->value)
return _imp->value;
@@ -686,6 +704,7 @@ namespace paludis
{
const tr1::shared_ptr<const PackageID> id;
const FSEntry filename;
+ mutable Mutex value_mutex;
mutable tr1::shared_ptr<time_t> value;
Implementation(const tr1::shared_ptr<const PackageID> & i, const FSEntry & v) :
@@ -711,6 +730,8 @@ ECTimeKey::~ECTimeKey()
const time_t
ECTimeKey::value() const
{
+ Lock l(_imp->value_mutex);
+
if (_imp->value)
return *_imp->value;
diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc
index 9aa3eb0..0f1aece 100644
--- a/paludis/repositories/e/e_repository.cc
+++ b/paludis/repositories/e/e_repository.cc
@@ -56,6 +56,7 @@
#include <paludis/util/stringify.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/set.hh>
#include <paludis/util/tr1_functional.hh>
@@ -102,23 +103,32 @@ namespace paludis
tr1::shared_ptr<RepositoryNameCache> names_cache;
+ mutable Mutex repo_mask_mutex;
mutable RepositoryMaskMap repo_mask;
mutable bool has_repo_mask;
- mutable VirtualsMap our_virtuals;
const std::map<QualifiedPackageName, QualifiedPackageName> provide_map;
+ mutable Mutex arch_flags_mutex;
mutable tr1::shared_ptr<UseFlagNameSet> arch_flags;
+ mutable Mutex mirrors_mutex;
mutable bool has_mirrors;
mutable MirrorMap mirrors;
+ mutable Mutex profiles_desc_mutex;
mutable bool has_profiles_desc;
mutable ProfilesDesc profiles_desc;
+
+ mutable Mutex use_desc_mutex;
mutable std::list<tr1::shared_ptr<UseDesc> > use_desc;
+ mutable Mutex profile_ptr_mutex;
mutable tr1::shared_ptr<ERepositoryProfile> profile_ptr;
+
+ mutable Mutex news_ptr_mutex;
mutable tr1::shared_ptr<ERepositoryNews> news_ptr;
+
mutable tr1::shared_ptr<ERepositorySets> sets_ptr;
mutable tr1::shared_ptr<ERepositoryEntries> entries_ptr;
mutable tr1::shared_ptr<Layout> layout;
@@ -155,6 +165,8 @@ namespace paludis
void
Implementation<ERepository>::need_profiles() const
{
+ Lock l(profile_ptr_mutex);
+
if (profile_ptr)
return;
@@ -166,6 +178,8 @@ namespace paludis
void
Implementation<ERepository>::need_profiles_desc() const
{
+ Lock l(profiles_desc_mutex);
+
if (has_profiles_desc)
return;
@@ -343,6 +357,8 @@ ERepository::do_package_ids(const QualifiedPackageName & n) const
bool
ERepository::repository_masked(const PackageID & id) const
{
+ Lock l(_imp->repo_mask_mutex);
+
if (! _imp->has_repo_mask)
{
Context context("When querying repository mask for '" + stringify(id) + "':");
@@ -419,6 +435,7 @@ ERepository::do_query_use_force(const UseFlagName & u, const PackageID & e) cons
tr1::shared_ptr<const UseFlagNameSet>
ERepository::do_arch_flags() const
{
+ Lock l(_imp->arch_flags_mutex);
if (! _imp->arch_flags)
{
Context context("When loading arch list:");
@@ -469,6 +486,8 @@ ERepository::do_license_exists(const std::string & license) const
void
ERepository::need_mirrors() const
{
+ Lock l(_imp->mirrors_mutex);
+
if (! _imp->has_mirrors)
{
bool found_one(false);
@@ -576,6 +595,8 @@ ERepository::invalidate()
void
ERepository::update_news() const
{
+ Lock l(_imp->news_ptr_mutex);
+
if (! _imp->news_ptr)
_imp->news_ptr.reset(new ERepositoryNews(_imp->params.environment, this, _imp->params));
@@ -876,6 +897,8 @@ std::string
ERepository::do_describe_use_flag(const UseFlagName & f,
const PackageID & e) const
{
+ Lock l(_imp->use_desc_mutex);
+
if (_imp->use_desc.empty())
{
std::string expand_sep(stringify(EAPIData::get_instance()->eapi_from_string(
diff --git a/paludis/repositories/e/e_repository_news.cc b/paludis/repositories/e/e_repository_news.cc
index ab09ecb..205c691 100644
--- a/paludis/repositories/e/e_repository_news.cc
+++ b/paludis/repositories/e/e_repository_news.cc
@@ -212,9 +212,9 @@ namespace paludis
template<>
struct Implementation<NewsFile>
{
- mutable std::list<std::string> display_if_installed;
- mutable std::list<std::string> display_if_keyword;
- mutable std::list<std::string> display_if_profile;
+ std::list<std::string> display_if_installed;
+ std::list<std::string> display_if_keyword;
+ std::list<std::string> display_if_profile;
};
}
diff --git a/paludis/repositories/e/ebuild_entries.cc b/paludis/repositories/e/ebuild_entries.cc
index 56ba7cc..d92c8eb 100644
--- a/paludis/repositories/e/ebuild_entries.cc
+++ b/paludis/repositories/e/ebuild_entries.cc
@@ -120,7 +120,7 @@ namespace
public ConstVisitor<URISpecTree>::VisitConstSequence<AAFinder, UseDepSpec>
{
private:
- mutable std::list<const URIDepSpec *> _specs;
+ std::list<const URIDepSpec *> _specs;
public:
void visit_leaf(const URIDepSpec & a)
diff --git a/paludis/repositories/e/ebuild_id.cc b/paludis/repositories/e/ebuild_id.cc
index be089f8..73189d9 100644
--- a/paludis/repositories/e/ebuild_id.cc
+++ b/paludis/repositories/e/ebuild_id.cc
@@ -37,6 +37,7 @@
#include <paludis/util/fs_entry.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/log.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/idle_action_pool.hh>
#include <paludis/util/visitor-impl.hh>
@@ -69,6 +70,8 @@ namespace paludis
template <>
struct Implementation<EbuildID>
{
+ Mutex mutex;
+
const QualifiedPackageName name;
const VersionSpec version;
const Environment * const environment;
@@ -133,6 +136,8 @@ EbuildID::~EbuildID()
void
EbuildID::need_keys_added() const
{
+ Lock l(_imp->mutex);
+
if (_imp->has_keys)
return;
@@ -317,6 +322,8 @@ namespace
void
EbuildID::need_masks_added() const
{
+ Lock l(_imp->mutex);
+
if (_imp->has_masks)
return;
@@ -591,12 +598,14 @@ EbuildID::extra_hash_value() const
void
EbuildID::set_eapi(const std::string & s) const
{
+ Lock l(_imp->mutex);
_imp->eapi = EAPIData::get_instance()->eapi_from_string(s);
}
void
EbuildID::set_slot(const SlotName & s) const
{
+ Lock l(_imp->mutex);
_imp->slot.reset(new SlotName(s));
}
@@ -609,6 +618,7 @@ EbuildID::e_repository() const
void
EbuildID::load_short_description(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->short_description.reset(new EStringKey(shared_from_this(), r, h, v, mkt_significant));
add_metadata_key(_imp->short_description);
}
@@ -616,6 +626,7 @@ EbuildID::load_short_description(const std::string & r, const std::string & h, c
void
EbuildID::load_build_depend(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->build_dependencies.reset(new EDependenciesKey(shared_from_this(), r, h, v, mkt_dependencies));
add_metadata_key(_imp->build_dependencies);
}
@@ -623,6 +634,7 @@ EbuildID::load_build_depend(const std::string & r, const std::string & h, const
void
EbuildID::load_run_depend(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->run_dependencies.reset(new EDependenciesKey(shared_from_this(), r, h, v, mkt_dependencies));
add_metadata_key(_imp->run_dependencies);
}
@@ -630,6 +642,7 @@ EbuildID::load_run_depend(const std::string & r, const std::string & h, const st
void
EbuildID::load_post_depend(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->post_dependencies.reset(new EDependenciesKey(shared_from_this(), r, h, v, mkt_dependencies));
add_metadata_key(_imp->post_dependencies);
}
@@ -637,6 +650,7 @@ EbuildID::load_post_depend(const std::string & r, const std::string & h, const s
void
EbuildID::load_src_uri(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->src_uri.reset(new EURIKey(shared_from_this(), r, h, v, mkt_dependencies));
add_metadata_key(_imp->src_uri);
}
@@ -644,6 +658,7 @@ EbuildID::load_src_uri(const std::string & r, const std::string & h, const std::
void
EbuildID::load_homepage(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->homepage.reset(new EURIKey(shared_from_this(), r, h, v, mkt_significant));
add_metadata_key(_imp->homepage);
}
@@ -651,6 +666,7 @@ EbuildID::load_homepage(const std::string & r, const std::string & h, const std:
void
EbuildID::load_license(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->license.reset(new ELicenseKey(shared_from_this(), r, h, v, mkt_normal));
add_metadata_key(_imp->license);
}
@@ -658,6 +674,7 @@ EbuildID::load_license(const std::string & r, const std::string & h, const std::
void
EbuildID::load_restrict(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->restrictions.reset(new ERestrictKey(shared_from_this(), r, h, v, mkt_internal));
add_metadata_key(_imp->restrictions);
}
@@ -665,6 +682,7 @@ EbuildID::load_restrict(const std::string & r, const std::string & h, const std:
void
EbuildID::load_provide(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->provide.reset(new EProvideKey(shared_from_this(), r, h, v, mkt_dependencies));
add_metadata_key(_imp->provide);
}
@@ -672,6 +690,7 @@ EbuildID::load_provide(const std::string & r, const std::string & h, const std::
void
EbuildID::load_iuse(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->iuse.reset(new EIUseKey(shared_from_this(), r, h, v, mkt_normal));
add_metadata_key(_imp->iuse);
}
@@ -679,6 +698,7 @@ EbuildID::load_iuse(const std::string & r, const std::string & h, const std::str
void
EbuildID::load_keywords(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->keywords.reset(new EKeywordsKey(shared_from_this(), r, h, v, mkt_normal));
add_metadata_key(_imp->keywords);
}
@@ -686,6 +706,7 @@ EbuildID::load_keywords(const std::string & r, const std::string & h, const std:
void
EbuildID::load_inherited(const std::string & r, const std::string & h, const std::string & v) const
{
+ Lock l(_imp->mutex);
_imp->inherited.reset(new EInheritedKey(shared_from_this(), r, h, v, mkt_internal));
add_metadata_key(_imp->inherited);
}
diff --git a/paludis/repositories/e/eclass_mtimes.cc b/paludis/repositories/e/eclass_mtimes.cc
index 60a630c..a7d3dbc 100644
--- a/paludis/repositories/e/eclass_mtimes.cc
+++ b/paludis/repositories/e/eclass_mtimes.cc
@@ -22,6 +22,7 @@
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/fs_entry.hh>
+#include <paludis/util/mutex.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
@@ -33,6 +34,7 @@ namespace paludis
struct Implementation<EclassMtimes>
{
tr1::shared_ptr<const FSEntrySequence> eclass_dirs;
+ mutable Mutex mutex;
mutable MakeHashedMap<std::string, time_t>::Type eclass_mtimes;
Implementation(tr1::shared_ptr<const FSEntrySequence> d) :
@@ -54,6 +56,8 @@ EclassMtimes::~EclassMtimes()
time_t
EclassMtimes::mtime(const std::string & e) const
{
+ Lock l(_imp->mutex);
+
MakeHashedMap<std::string, time_t>::Type::const_iterator i(_imp->eclass_mtimes.find(e));
if (i != _imp->eclass_mtimes.end())
return i->second;
diff --git a/paludis/repositories/e/exheres_layout.cc b/paludis/repositories/e/exheres_layout.cc
index 0abd938..648f260 100644
--- a/paludis/repositories/e/exheres_layout.cc
+++ b/paludis/repositories/e/exheres_layout.cc
@@ -30,6 +30,7 @@
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/tr1_functional.hh>
#include <paludis/util/log.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/is_file_with_extension.hh>
#include <paludis/util/iterator.hh>
@@ -58,6 +59,8 @@ namespace paludis
const ERepository * const repository;
const FSEntry tree_root;
+ mutable Mutex big_nasty_mutex;
+
mutable bool has_category_names;
mutable CategoryMap category_names;
mutable PackagesMap package_names;
@@ -117,6 +120,8 @@ ExheresLayout::~ExheresLayout()
void
ExheresLayout::need_category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->has_category_names)
return;
@@ -167,6 +172,8 @@ ExheresLayout::need_category_names() const
void
ExheresLayout::need_package_ids(const QualifiedPackageName & n) const
{
+ Lock l(_imp->big_nasty_mutex);
+
using namespace tr1::placeholders;
if (_imp->package_names[n])
@@ -210,6 +217,8 @@ ExheresLayout::need_package_ids(const QualifiedPackageName & n) const
bool
ExheresLayout::has_category_named(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When checking for category '" + stringify(c) + "' in '" + stringify(_imp->repository->name()) + "':");
need_category_names();
@@ -219,6 +228,8 @@ ExheresLayout::has_category_named(const CategoryNamePart & c) const
bool
ExheresLayout::has_package_named(const QualifiedPackageName & q) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When checking for package '" + stringify(q) + "' in '" + stringify(_imp->repository->name()) + ":");
need_category_names();
@@ -253,6 +264,8 @@ ExheresLayout::has_package_named(const QualifiedPackageName & q) const
void
ExheresLayout::need_category_names_collection() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->category_names_collection)
return;
@@ -267,6 +280,8 @@ ExheresLayout::need_category_names_collection() const
tr1::shared_ptr<const CategoryNamePartSet>
ExheresLayout::category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When fetching category names in " + stringify(stringify(_imp->repository->name())) + ":");
need_category_names_collection();
@@ -276,6 +291,8 @@ ExheresLayout::category_names() const
tr1::shared_ptr<const QualifiedPackageNameSet>
ExheresLayout::package_names(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
using namespace tr1::placeholders;
/* this isn't particularly fast because it isn't called very often. avoid
@@ -328,6 +345,8 @@ ExheresLayout::package_names(const CategoryNamePart & c) const
tr1::shared_ptr<const PackageIDSequence>
ExheresLayout::package_ids(const QualifiedPackageName & n) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When fetching versions of '" + stringify(n) + "' in " + stringify(_imp->repository->name()) + ":");
if (has_package_named(n))
diff --git a/paludis/repositories/e/traditional_layout.cc b/paludis/repositories/e/traditional_layout.cc
index a4fd202..292d719 100644
--- a/paludis/repositories/e/traditional_layout.cc
+++ b/paludis/repositories/e/traditional_layout.cc
@@ -34,6 +34,7 @@
#include <paludis/util/iterator.hh>
#include <paludis/util/strip.hh>
#include <paludis/util/sequence.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/set.hh>
#include <paludis/util/tr1_functional.hh>
@@ -58,6 +59,8 @@ namespace paludis
const ERepository * const repository;
const FSEntry tree_root;
+ mutable Mutex big_nasty_mutex;
+
mutable bool has_category_names;
mutable CategoryMap category_names;
mutable PackagesMap package_names;
@@ -117,6 +120,8 @@ TraditionalLayout::~TraditionalLayout()
void
TraditionalLayout::need_category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->has_category_names)
return;
@@ -187,6 +192,8 @@ TraditionalLayout::need_category_names() const
void
TraditionalLayout::need_package_ids(const QualifiedPackageName & n) const
{
+ Lock l(_imp->big_nasty_mutex);
+
using namespace tr1::placeholders;
if (_imp->package_names[n])
@@ -230,6 +237,8 @@ TraditionalLayout::need_package_ids(const QualifiedPackageName & n) const
bool
TraditionalLayout::has_category_named(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When checking for category '" + stringify(c) + "' in '" + stringify(_imp->repository->name()) + "':");
need_category_names();
@@ -239,6 +248,8 @@ TraditionalLayout::has_category_named(const CategoryNamePart & c) const
bool
TraditionalLayout::has_package_named(const QualifiedPackageName & q) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When checking for package '" + stringify(q) + "' in '" + stringify(_imp->repository->name()) + ":");
need_category_names();
@@ -272,6 +283,8 @@ TraditionalLayout::has_package_named(const QualifiedPackageName & q) const
void
TraditionalLayout::need_category_names_collection() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->category_names_collection)
return;
@@ -286,6 +299,8 @@ TraditionalLayout::need_category_names_collection() const
tr1::shared_ptr<const CategoryNamePartSet>
TraditionalLayout::category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When fetching category names in " + stringify(stringify(_imp->repository->name())) + ":");
need_category_names_collection();
@@ -295,6 +310,8 @@ TraditionalLayout::category_names() const
tr1::shared_ptr<const QualifiedPackageNameSet>
TraditionalLayout::package_names(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
using namespace tr1::placeholders;
/* this isn't particularly fast because it isn't called very often. avoid
@@ -347,6 +364,8 @@ TraditionalLayout::package_names(const CategoryNamePart & c) const
tr1::shared_ptr<const PackageIDSequence>
TraditionalLayout::package_ids(const QualifiedPackageName & n) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When fetching versions of '" + stringify(n) + "' in " + stringify(_imp->repository->name()) + ":");
if (has_package_named(n))
diff --git a/paludis/repositories/e/vdb_id.cc b/paludis/repositories/e/vdb_id.cc
index 097b497..52d57fb 100644
--- a/paludis/repositories/e/vdb_id.cc
+++ b/paludis/repositories/e/vdb_id.cc
@@ -34,6 +34,7 @@
#include <paludis/util/log.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/strip.hh>
+#include <paludis/util/mutex.hh>
#include <iterator>
#include <fstream>
@@ -58,6 +59,8 @@ namespace paludis
template <>
struct Implementation<VDBID>
{
+ mutable Mutex mutex;
+
const QualifiedPackageName name;
const VersionSpec version;
const Environment * const environment;
@@ -125,6 +128,8 @@ VDBID::~VDBID()
void
VDBID::need_keys_added() const
{
+ Lock l(_imp->mutex);
+
if (_imp->has_keys)
return;
_imp->has_keys = true;
@@ -370,6 +375,8 @@ VDBID::version() const
const SlotName
VDBID::slot() const
{
+ Lock l(_imp->mutex);
+
if (_imp->slot)
return *_imp->slot;
@@ -396,6 +403,8 @@ VDBID::repository() const
const tr1::shared_ptr<const EAPI>
VDBID::eapi() const
{
+ Lock l(_imp->mutex);
+
if (_imp->eapi)
return _imp->eapi;
diff --git a/paludis/repositories/e/vdb_repository.cc b/paludis/repositories/e/vdb_repository.cc
index 3fdc07f..243d96f 100644
--- a/paludis/repositories/e/vdb_repository.cc
+++ b/paludis/repositories/e/vdb_repository.cc
@@ -49,6 +49,7 @@
#include <paludis/util/tr1_functional.hh>
#include <paludis/util/dir_iterator.hh>
#include <paludis/util/fast_unique_copy.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/fs_entry.hh>
#include <paludis/util/is_file_with_extension.hh>
#include <paludis/util/iterator.hh>
@@ -99,6 +100,8 @@ namespace paludis
{
VDBRepositoryParams params;
+ mutable Mutex big_nasty_mutex;
+
mutable CategoryMap categories;
mutable bool has_category_names;
mutable IDMap ids;
@@ -164,6 +167,8 @@ VDBRepository::~VDBRepository()
bool
VDBRepository::do_has_category_named(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When checking for category '" + stringify(c) +
"' in " + stringify(name()) + ":");
@@ -174,6 +179,8 @@ VDBRepository::do_has_category_named(const CategoryNamePart & c) const
bool
VDBRepository::do_has_package_named(const QualifiedPackageName & q) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When checking for package '" + stringify(q) +
"' in " + stringify(name()) + ":");
@@ -191,6 +198,8 @@ VDBRepository::do_has_package_named(const QualifiedPackageName & q) const
tr1::shared_ptr<const CategoryNamePartSet>
VDBRepository::do_category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When fetching category names in " + stringify(name()) + ":");
need_category_names();
@@ -207,6 +216,8 @@ VDBRepository::do_category_names() const
tr1::shared_ptr<const QualifiedPackageNameSet>
VDBRepository::do_package_names(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When fetching package names in category '" + stringify(c)
+ "' in " + stringify(name()) + ":");
@@ -224,6 +235,8 @@ VDBRepository::do_package_names(const CategoryNamePart & c) const
tr1::shared_ptr<const PackageIDSequence>
VDBRepository::do_package_ids(const QualifiedPackageName & n) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When fetching versions of '" + stringify(n) + "' in "
+ stringify(name()) + ":");
@@ -242,6 +255,8 @@ VDBRepository::do_package_ids(const QualifiedPackageName & n) const
UseFlagState
VDBRepository::do_query_use(const UseFlagName & f, const PackageID & e) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (! e.use_key())
return use_unspecified;
@@ -531,12 +546,16 @@ VDBRepository::sets_list() const
void
VDBRepository::invalidate()
{
+ Lock l(_imp->big_nasty_mutex);
+
_imp.reset(new Implementation<VDBRepository>(this, _imp->params));
}
void
VDBRepository::add_string_to_world(const std::string & n) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When adding '" + n + "' to world file '" + stringify(_imp->params.world) + "':");
if (! _imp->params.world.exists())
@@ -563,6 +582,8 @@ VDBRepository::add_string_to_world(const std::string & n) const
void
VDBRepository::remove_string_from_world(const std::string & n) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When removing '" + n + "' from world file '" + stringify(_imp->params.world) + "':");
if (_imp->params.world.exists())
@@ -648,6 +669,8 @@ VDBRepository::get_environment_variable(
tr1::shared_ptr<const RepositoryProvidesInterface::ProvidesSequence>
VDBRepository::provided_packages() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->provides)
return _imp->provides;
@@ -684,6 +707,8 @@ VDBRepository::do_use_expand_hidden_prefixes() const
bool
VDBRepository::load_provided_using_cache() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->params.provides_cache == FSEntry("/var/empty"))
return false;
@@ -757,6 +782,8 @@ VDBRepository::load_provided_using_cache() const
void
VDBRepository::load_provided_the_slow_way() const
{
+ Lock l(_imp->big_nasty_mutex);
+
using namespace tr1::placeholders;
Context context("When loading VDB PROVIDEs map the slow way:");
@@ -823,6 +850,8 @@ VDBRepository::load_provided_the_slow_way() const
void
VDBRepository::regenerate_cache() const
{
+ Lock l(_imp->big_nasty_mutex);
+
regenerate_provides_cache();
_imp->names_cache->regenerate_cache();
}
@@ -830,6 +859,8 @@ VDBRepository::regenerate_cache() const
void
VDBRepository::regenerate_provides_cache() const
{
+ Lock l(_imp->big_nasty_mutex);
+
using namespace tr1::placeholders;
if (_imp->params.provides_cache == FSEntry("/var/empty"))
@@ -882,6 +913,8 @@ VDBRepository::regenerate_provides_cache() const
tr1::shared_ptr<const CategoryNamePartSet>
VDBRepository::do_category_names_containing_package(const PackageNamePart & p) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (! _imp->names_cache->usable())
return Repository::do_category_names_containing_package(p);
@@ -1022,6 +1055,8 @@ VDBRepository::perform_hook(const Hook & hook) const
void
VDBRepository::need_category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->has_category_names)
return;
@@ -1046,6 +1081,8 @@ VDBRepository::need_category_names() const
void
VDBRepository::need_package_ids(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->categories[c])
return;
@@ -1083,6 +1120,8 @@ VDBRepository::need_package_ids(const CategoryNamePart & c) const
const tr1::shared_ptr<const PackageID>
VDBRepository::make_id(const QualifiedPackageName & q, const VersionSpec & v, const FSEntry & f) const
{
+ Lock l(_imp->big_nasty_mutex);
+
Context context("When creating ID for '" + stringify(q) + "-" + stringify(v) + "' from '" + stringify(f) + "':");
tr1::shared_ptr<VDBID> result(new VDBID(q, v, _imp->params.environment, shared_from_this(), f));
@@ -1092,6 +1131,8 @@ VDBRepository::make_id(const QualifiedPackageName & q, const VersionSpec & v, co
const tr1::shared_ptr<const PackageID>
VDBRepository::package_id_if_exists(const QualifiedPackageName & q, const VersionSpec & v) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (! has_package_named(q))
return tr1::shared_ptr<const PackageID>();
diff --git a/paludis/repositories/fake/fake_package_id.cc b/paludis/repositories/fake/fake_package_id.cc
index 303fd2b..becdccb 100644
--- a/paludis/repositories/fake/fake_package_id.cc
+++ b/paludis/repositories/fake/fake_package_id.cc
@@ -27,6 +27,7 @@
#include <paludis/portage_dep_parser.hh>
#include <paludis/hashed_containers.hh>
#include <paludis/util/stringify.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/iterator.hh>
@@ -277,6 +278,8 @@ namespace paludis
template <>
struct Implementation<FakePackageID>
{
+ mutable Mutex mutex;
+
const Environment * const env;
const tr1::shared_ptr<const FakeRepositoryBase> repository;
const QualifiedPackageName name;
@@ -659,6 +662,8 @@ namespace
void
FakePackageID::need_masks_added() const
{
+ Lock l(_imp->mutex);
+
if (_imp->has_masks)
return;
diff --git a/paludis/repositories/gems/gem_specification.cc b/paludis/repositories/gems/gem_specification.cc
index bd9c74e..abbc8e4 100644
--- a/paludis/repositories/gems/gem_specification.cc
+++ b/paludis/repositories/gems/gem_specification.cc
@@ -21,6 +21,7 @@
#include <paludis/repositories/gems/yaml.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/tr1_functional.hh>
#include <paludis/util/stringify.hh>
#include <paludis/name.hh>
@@ -73,6 +74,8 @@ namespace paludis
template <>
struct Implementation<GemSpecification>
{
+ mutable Mutex mutex;
+
std::string name_part;
std::string version;
std::string date;
@@ -610,6 +613,8 @@ GemSpecification::perform_action(Action & a) const
void
GemSpecification::need_masks_added() const
{
+ Lock l(_imp->mutex);
+
if (_imp->has_masks)
return;
diff --git a/paludis/repositories/gems/gems_repository.cc b/paludis/repositories/gems/gems_repository.cc
index 20abc71..cfb8dd2 100644
--- a/paludis/repositories/gems/gems_repository.cc
+++ b/paludis/repositories/gems/gems_repository.cc
@@ -29,6 +29,7 @@
#include <paludis/util/system.hh>
#include <paludis/util/set.hh>
#include <paludis/util/sequence.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/eapi.hh>
#include <paludis/hashed_containers.hh>
@@ -46,6 +47,8 @@ namespace paludis
{
const gems::RepositoryParams params;
+ mutable Mutex big_nasty_mutex;
+
mutable tr1::shared_ptr<const CategoryNamePartSet> category_names;
mutable MakeHashedMap<CategoryNamePart, tr1::shared_ptr<const QualifiedPackageNameSet> >::Type package_names;
mutable MakeHashedMap<QualifiedPackageName, tr1::shared_ptr<PackageIDSequence> >::Type ids;
@@ -101,12 +104,16 @@ GemsRepository::~GemsRepository()
void
GemsRepository::invalidate()
{
+ Lock l(_imp->big_nasty_mutex);
+
_imp.reset(new Implementation<GemsRepository>(_imp->params));
}
bool
GemsRepository::do_has_category_named(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
need_category_names();
return _imp->category_names->end() != _imp->category_names->find(c);
}
@@ -114,6 +121,8 @@ GemsRepository::do_has_category_named(const CategoryNamePart & c) const
bool
GemsRepository::do_has_package_named(const QualifiedPackageName & q) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (! do_has_category_named(q.category))
return false;
@@ -124,6 +133,8 @@ GemsRepository::do_has_package_named(const QualifiedPackageName & q) const
tr1::shared_ptr<const CategoryNamePartSet>
GemsRepository::do_category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
need_category_names();
return _imp->category_names;
}
@@ -131,6 +142,8 @@ GemsRepository::do_category_names() const
tr1::shared_ptr<const QualifiedPackageNameSet>
GemsRepository::do_package_names(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (! has_category_named(c))
return make_shared_ptr(new QualifiedPackageNameSet);
@@ -146,6 +159,8 @@ GemsRepository::do_package_names(const CategoryNamePart & c) const
tr1::shared_ptr<const PackageIDSequence>
GemsRepository::do_package_ids(const QualifiedPackageName & q) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (! has_package_named(q))
return make_shared_ptr(new PackageIDSequence);
@@ -162,6 +177,8 @@ GemsRepository::do_package_ids(const QualifiedPackageName & q) const
void
GemsRepository::need_category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->has_category_names)
return;
@@ -175,6 +192,8 @@ GemsRepository::need_category_names() const
void
GemsRepository::need_ids() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->has_ids)
return;
diff --git a/paludis/repositories/gems/installed_gems_repository.cc b/paludis/repositories/gems/installed_gems_repository.cc
index fee24f5..77776c3 100644
--- a/paludis/repositories/gems/installed_gems_repository.cc
+++ b/paludis/repositories/gems/installed_gems_repository.cc
@@ -34,6 +34,7 @@
#include <paludis/util/pstream.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/system.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/log.hh>
#include <paludis/util/strip.hh>
#include <paludis/hashed_containers.hh>
@@ -52,6 +53,8 @@ namespace paludis
template <>
struct Implementation<InstalledGemsRepository>
{
+ mutable Mutex big_nasty_mutex;
+
const gems::InstalledRepositoryParams params;
mutable tr1::shared_ptr<const CategoryNamePartSet> category_names;
@@ -106,12 +109,16 @@ InstalledGemsRepository::~InstalledGemsRepository()
void
InstalledGemsRepository::invalidate()
{
+ Lock l(_imp->big_nasty_mutex);
+
_imp.reset(new Implementation<InstalledGemsRepository>(_imp->params));
}
bool
InstalledGemsRepository::do_has_category_named(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
need_category_names();
return _imp->category_names->end() != _imp->category_names->find(c);
}
@@ -119,6 +126,8 @@ InstalledGemsRepository::do_has_category_named(const CategoryNamePart & c) const
bool
InstalledGemsRepository::do_has_package_named(const QualifiedPackageName & q) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (! do_has_category_named(q.category))
return false;
@@ -129,6 +138,8 @@ InstalledGemsRepository::do_has_package_named(const QualifiedPackageName & q) co
tr1::shared_ptr<const CategoryNamePartSet>
InstalledGemsRepository::do_category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
need_category_names();
return _imp->category_names;
}
@@ -136,6 +147,8 @@ InstalledGemsRepository::do_category_names() const
tr1::shared_ptr<const QualifiedPackageNameSet>
InstalledGemsRepository::do_package_names(const CategoryNamePart & c) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (! has_category_named(c))
return make_shared_ptr(new QualifiedPackageNameSet);
@@ -151,6 +164,8 @@ InstalledGemsRepository::do_package_names(const CategoryNamePart & c) const
tr1::shared_ptr<const PackageIDSequence>
InstalledGemsRepository::do_package_ids(const QualifiedPackageName & q) const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (! has_package_named(q))
return make_shared_ptr(new PackageIDSequence);
@@ -166,6 +181,8 @@ InstalledGemsRepository::do_package_ids(const QualifiedPackageName & q) const
void
InstalledGemsRepository::need_category_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->has_category_names)
return;
@@ -179,6 +196,8 @@ InstalledGemsRepository::need_category_names() const
void
InstalledGemsRepository::need_ids() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->has_ids)
return;
@@ -219,6 +238,8 @@ InstalledGemsRepository::need_ids() const
bool
InstalledGemsRepository::is_suitable_destination_for(const PackageID & e) const
{
+ Lock l(_imp->big_nasty_mutex);
+
std::string f(e.repository()->format());
return f == "gems";
}
diff --git a/paludis/repositories/gems/yaml.cc b/paludis/repositories/gems/yaml.cc
index b9fdc75..2ed6c94 100644
--- a/paludis/repositories/gems/yaml.cc
+++ b/paludis/repositories/gems/yaml.cc
@@ -184,6 +184,7 @@ MapNode::find(const std::string & s) const
namespace
{
+ static Mutex document_error_table_mutex;
static std::map<void *, std::string> document_error_table;
template <typename R_, typename T_>
@@ -260,6 +261,7 @@ namespace
void error_handler(SyckParser * p, char * s)
{
+ Lock l(document_error_table_mutex);
document_error_table[p] = s;
}
}
@@ -314,11 +316,14 @@ Document::Document(const std::string & s) :
SYMID root_id(syck_parse(_imp->parser.get()));
- if (document_error_table.end() != document_error_table.find(_imp->parser.get()))
{
- std::string e(document_error_table.find(_imp->parser.get())->second);
- document_error_table.erase(_imp->parser.get());
- throw ParseError(e);
+ Lock l(document_error_table_mutex);
+ if (document_error_table.end() != document_error_table.find(_imp->parser.get()))
+ {
+ std::string e(document_error_table.find(_imp->parser.get())->second);
+ document_error_table.erase(_imp->parser.get());
+ throw ParseError(e);
+ }
}
char * root_uncasted(0);
diff --git a/paludis/repositories/virtuals/installed_virtuals_repository.cc b/paludis/repositories/virtuals/installed_virtuals_repository.cc
index 625afef..8ae9a43 100644
--- a/paludis/repositories/virtuals/installed_virtuals_repository.cc
+++ b/paludis/repositories/virtuals/installed_virtuals_repository.cc
@@ -34,6 +34,7 @@
#include <paludis/util/set.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/map.hh>
+#include <paludis/util/mutex.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
@@ -53,6 +54,7 @@ namespace paludis
const Environment * const env;
const FSEntry root;
+ mutable Mutex ids_mutex;
mutable IDMap ids;
mutable bool has_ids;
@@ -131,6 +133,8 @@ InstalledVirtualsRepository::~InstalledVirtualsRepository()
void
InstalledVirtualsRepository::need_ids() const
{
+ Lock l(_imp->ids_mutex);
+
if (_imp->has_ids)
return;
diff --git a/paludis/repositories/virtuals/package_id.cc b/paludis/repositories/virtuals/package_id.cc
index 2198e3c..e65b3f6 100644
--- a/paludis/repositories/virtuals/package_id.cc
+++ b/paludis/repositories/virtuals/package_id.cc
@@ -24,6 +24,7 @@
#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/name.hh>
#include <paludis/dep_spec.hh>
#include <paludis/version_spec.hh>
@@ -122,6 +123,7 @@ namespace paludis
const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > bdep;
const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > rdep;
mutable bool has_masks;
+ mutable Mutex mutex;
Implementation(
const tr1::shared_ptr<const Repository> & o,
@@ -452,6 +454,8 @@ namespace
void
VirtualsPackageID::need_masks_added() const
{
+ Lock l(_imp->mutex);
+
if (_imp->has_masks)
return;
diff --git a/paludis/repositories/virtuals/virtuals_repository.cc b/paludis/repositories/virtuals/virtuals_repository.cc
index 217c7ee..408e911 100644
--- a/paludis/repositories/virtuals/virtuals_repository.cc
+++ b/paludis/repositories/virtuals/virtuals_repository.cc
@@ -37,6 +37,7 @@
#include <paludis/util/set.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/mutex.hh>
#include <vector>
#include <utility>
@@ -55,6 +56,8 @@ namespace paludis
{
const Environment * const env;
+ mutable Mutex big_nasty_mutex;
+
mutable std::vector<std::pair<QualifiedPackageName, tr1::shared_ptr<const PackageDepSpec> > > names;
mutable bool has_names;
@@ -126,6 +129,8 @@ VirtualsRepository::~VirtualsRepository()
void
VirtualsRepository::need_names() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->has_names)
return;
@@ -185,6 +190,8 @@ VirtualsRepository::need_names() const
void
VirtualsRepository::need_ids() const
{
+ Lock l(_imp->big_nasty_mutex);
+
if (_imp->has_ids)
return;
diff --git a/paludis/repository_name_cache.cc b/paludis/repository_name_cache.cc
index 28ff6f4..f152e8a 100644
--- a/paludis/repository_name_cache.cc
+++ b/paludis/repository_name_cache.cc
@@ -27,6 +27,7 @@
#include <paludis/util/set.hh>
#include <paludis/util/dir_iterator.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/mutex.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
#include <list>
@@ -41,6 +42,8 @@ namespace paludis
template<>
struct Implementation<RepositoryNameCache>
{
+ mutable Mutex mutex;
+
mutable FSEntry location;
const Repository * const repo;
@@ -72,6 +75,8 @@ RepositoryNameCache::~RepositoryNameCache()
tr1::shared_ptr<const CategoryNamePartSet>
RepositoryNameCache::category_names_containing_package(const PackageNamePart & p) const
{
+ Lock l(_imp->mutex);
+
if (! usable())
return tr1::shared_ptr<const CategoryNamePartSet>();
@@ -153,6 +158,8 @@ RepositoryNameCache::category_names_containing_package(const PackageNamePart & p
void
RepositoryNameCache::regenerate_cache() const
{
+ Lock l(_imp->mutex);
+
if (_imp->location == FSEntry("/var/empty"))
return;
diff --git a/paludis/set_file.cc b/paludis/set_file.cc
index 81e40fc..42cc041 100644
--- a/paludis/set_file.cc
+++ b/paludis/set_file.cc
@@ -25,6 +25,7 @@
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/options.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/config_file.hh>
#include <paludis/environment.hh>
#include <paludis/query.hh>
@@ -66,6 +67,8 @@ namespace
public SetFileHandler
{
private:
+ mutable Mutex _mutex;
+
const SetFileParams _p;
std::list<std::string> _lines;
mutable tr1::shared_ptr<ConstTreeSequence<SetSpecTree, AllDepSpec> > _contents;
@@ -101,6 +104,8 @@ namespace
public SetFileHandler
{
private:
+ mutable Mutex _mutex;
+
const SetFileParams _p;
std::list<std::string> _lines;
mutable tr1::shared_ptr<ConstTreeSequence<SetSpecTree, AllDepSpec> > _contents;
@@ -296,6 +301,8 @@ SimpleHandler::_create_contents() const
tr1::shared_ptr<SetSpecTree::ConstItem>
SimpleHandler::contents() const
{
+ Lock l(_mutex);
+
if (! _contents)
_create_contents();
@@ -305,6 +312,8 @@ SimpleHandler::contents() const
void
SimpleHandler::add(const std::string & p)
{
+ Lock l(_mutex);
+
if (_lines.end() == std::find(_lines.begin(), _lines.end(), p))
_lines.push_back(p);
@@ -314,6 +323,8 @@ SimpleHandler::add(const std::string & p)
void
SimpleHandler::remove(const std::string & p)
{
+ Lock l(_mutex);
+
Context context("When removing '" + stringify(p) + "' from simple set file '" + stringify(_p.file_name) + "':");
_contents.reset();
@@ -323,6 +334,8 @@ SimpleHandler::remove(const std::string & p)
void
SimpleHandler::rewrite() const
{
+ Lock l(_mutex);
+
Context context("When rewriting simple set file '" + stringify(_p.file_name) + "':");
std::ofstream f(stringify(_p.file_name).c_str());
@@ -360,6 +373,8 @@ PaludisConfHandler::_create_contents() const
tr1::shared_ptr<SetSpecTree::ConstItem>
PaludisConfHandler::contents() const
{
+ Lock l(_mutex);
+
if (! _contents)
_create_contents();
@@ -369,6 +384,8 @@ PaludisConfHandler::contents() const
void
PaludisConfHandler::add(const std::string & p)
{
+ Lock l(_mutex);
+
if (_lines.end() == std::find_if(_lines.begin(), _lines.end(), TokenOneIs(p)))
_lines.push_back("* " + p);
@@ -380,6 +397,8 @@ PaludisConfHandler::remove(const std::string & p)
{
Context context("When removing '" + stringify(p) + "' from paludis conf set file '" + stringify(_p.file_name) + "':");
+ Lock l(_mutex);
+
_contents.reset();
_lines.remove_if(TokenOneIs(p));
}
@@ -389,6 +408,8 @@ PaludisConfHandler::rewrite() const
{
Context context("When rewriting paludis conf set file '" + stringify(_p.file_name) + "':");
+ Lock l(_mutex);
+
std::ofstream f(stringify(_p.file_name).c_str());
if (! f)
throw SetFileError(_p.file_name, "Cannot write to '" + stringify(_p.file_name) + "'");
diff --git a/paludis/util/fs_entry.cc b/paludis/util/fs_entry.cc
index 330da60..8bbe31b 100644
--- a/paludis/util/fs_entry.cc
+++ b/paludis/util/fs_entry.cc
@@ -20,6 +20,7 @@
#include <paludis/util/exception.hh>
#include <paludis/util/fs_entry.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/sequence-impl.hh>
@@ -52,20 +53,40 @@ FSError::FSError(const std::string & our_message) throw () :
{
}
+namespace paludis
+{
+ template <>
+ struct Implementation<FSEntry>
+ {
+ std::string path;
+
+ mutable Mutex mutex;
+ mutable tr1::shared_ptr<struct ::stat> stat_info;
+ mutable bool exists;
+ mutable bool checked;
+
+ Implementation(const std::string & p) :
+ path(p),
+ exists(false),
+ checked(false)
+ {
+ }
+ };
+}
+
FSEntry::FSEntry(const std::string & path) :
- _path(path),
- _exists(false),
- _checked(false)
+ PrivateImplementationPattern<FSEntry>(new Implementation<FSEntry>(path))
{
_normalise();
}
FSEntry::FSEntry(const FSEntry & other) :
- _path(other._path),
- _stat_info(other._stat_info),
- _exists(other._exists),
- _checked(other._checked)
+ PrivateImplementationPattern<FSEntry>(new Implementation<FSEntry>(other._imp->path))
{
+ Lock l(other._imp->mutex);
+ _imp->stat_info = other._imp->stat_info;
+ _imp->exists = other._imp->exists;
+ _imp->checked = other._imp->checked;
}
FSEntry::~FSEntry()
@@ -75,10 +96,11 @@ FSEntry::~FSEntry()
const FSEntry &
FSEntry::operator= (const FSEntry & other)
{
- _path = other._path;
- _stat_info = other._stat_info;
- _exists = other._exists;
- _checked = other._checked;
+ Lock l(other._imp->mutex);
+ _imp->path = other._imp->path;
+ _imp->stat_info = other._imp->stat_info;
+ _imp->exists = other._imp->exists;
+ _imp->checked = other._imp->checked;
return *this;
}
@@ -86,20 +108,20 @@ FSEntry::operator= (const FSEntry & other)
const FSEntry &
FSEntry::operator/= (const FSEntry & rhs)
{
- if (_path.empty() || '/' != _path.at(_path.length() - 1))
- _path.append("/");
+ if (_imp->path.empty() || '/' != _imp->path.at(_imp->path.length() - 1))
+ _imp->path.append("/");
- if (! rhs._path.empty())
+ if (! rhs._imp->path.empty())
{
- if ('/' == rhs._path.at(0))
- _path.append(rhs._path.substr(1));
+ if ('/' == rhs._imp->path.at(0))
+ _imp->path.append(rhs._imp->path.substr(1));
else
- _path.append(rhs._path);
+ _imp->path.append(rhs._imp->path);
}
- _checked = false;
- _exists = false;
- _stat_info.reset();
+ _imp->checked = false;
+ _imp->exists = false;
+ _imp->stat_info.reset();
return *this;
}
@@ -113,13 +135,13 @@ FSEntry::operator/ (const std::string & rhs) const
bool
FSEntry::operator< (const FSEntry & other) const
{
- return _path < other._path;
+ return _imp->path < other._imp->path;
}
bool
FSEntry::operator== (const FSEntry & other) const
{
- return _path == other._path;
+ return _imp->path == other._imp->path;
}
bool
@@ -127,7 +149,7 @@ FSEntry::exists() const
{
_stat();
- return _exists;
+ return _imp->exists;
}
bool
@@ -135,8 +157,8 @@ FSEntry::is_directory() const
{
_stat();
- if (_exists)
- return S_ISDIR((*_stat_info).st_mode);
+ if (_imp->exists)
+ return S_ISDIR((*_imp->stat_info).st_mode);
return false;
}
@@ -146,8 +168,8 @@ FSEntry::is_directory_or_symlink_to_directory() const
{
_stat();
- if (_exists)
- return S_ISDIR((*_stat_info).st_mode) ||
+ if (_imp->exists)
+ return S_ISDIR((*_imp->stat_info).st_mode) ||
(is_symbolic_link() && realpath_if_exists().is_directory());
return false;
@@ -158,8 +180,8 @@ FSEntry::is_fifo() const
{
_stat();
- if (_exists)
- return S_ISFIFO((*_stat_info).st_mode);
+ if (_imp->exists)
+ return S_ISFIFO((*_imp->stat_info).st_mode);
return false;
}
@@ -169,8 +191,8 @@ FSEntry::is_device() const
{
_stat();
- if (_exists)
- return S_ISBLK((*_stat_info).st_mode) || S_ISCHR((*_stat_info).st_mode);
+ if (_imp->exists)
+ return S_ISBLK((*_imp->stat_info).st_mode) || S_ISCHR((*_imp->stat_info).st_mode);
return false;
}
@@ -180,8 +202,8 @@ FSEntry::is_regular_file() const
{
_stat();
- if (_exists)
- return S_ISREG((*_stat_info).st_mode);
+ if (_imp->exists)
+ return S_ISREG((*_imp->stat_info).st_mode);
return false;
}
@@ -191,8 +213,8 @@ FSEntry::is_regular_file_or_symlink_to_regular_file() const
{
_stat();
- if (_exists)
- return S_ISREG((*_stat_info).st_mode) ||
+ if (_imp->exists)
+ return S_ISREG((*_imp->stat_info).st_mode) ||
(is_symbolic_link() && realpath_if_exists().is_regular_file());
return false;
@@ -203,8 +225,8 @@ FSEntry::is_symbolic_link() const
{
_stat();
- if (_exists)
- return S_ISLNK((*_stat_info).st_mode);
+ if (_imp->exists)
+ return S_ISLNK((*_imp->stat_info).st_mode);
return false;
}
@@ -213,12 +235,12 @@ FSEntry::is_symbolic_link() const
bool
FSEntry::has_permission(const FSUserGroup & user_group, const FSPermission & fs_perm) const
{
- Context context("When checking permissions on '" + stringify(_path) + "':");
+ Context context("When checking permissions on '" + stringify(_imp->path) + "':");
_stat();
- if (! _exists)
- throw FSError("Filesystem entry '" + _path + "' does not exist");
+ if (! _imp->exists)
+ throw FSError("Filesystem entry '" + _imp->path + "' does not exist");
switch (user_group)
{
@@ -227,11 +249,11 @@ FSEntry::has_permission(const FSUserGroup & user_group, const FSPermission & fs_
switch (fs_perm)
{
case fs_perm_read:
- return (*_stat_info).st_mode & S_IRUSR;
+ return (*_imp->stat_info).st_mode & S_IRUSR;
case fs_perm_write:
- return (*_stat_info).st_mode & S_IWUSR;
+ return (*_imp->stat_info).st_mode & S_IWUSR;
case fs_perm_execute:
- return (*_stat_info).st_mode & S_IXUSR;
+ return (*_imp->stat_info).st_mode & S_IXUSR;
}
throw InternalError(PALUDIS_HERE, "Unhandled FSPermission");
}
@@ -240,11 +262,11 @@ FSEntry::has_permission(const FSUserGroup & user_group, const FSPermission & fs_
switch (fs_perm)
{
case fs_perm_read:
- return (*_stat_info).st_mode & S_IRGRP;
+ return (*_imp->stat_info).st_mode & S_IRGRP;
case fs_perm_write:
- return (*_stat_info).st_mode & S_IWGRP;
+ return (*_imp->stat_info).st_mode & S_IWGRP;
case fs_perm_execute:
- return (*_stat_info).st_mode & S_IXGRP;
+ return (*_imp->stat_info).st_mode & S_IXGRP;
}
throw InternalError(PALUDIS_HERE, "Unhandled FSPermission");
}
@@ -253,11 +275,11 @@ FSEntry::has_permission(const FSUserGroup & user_group, const FSPermission & fs_
switch (fs_perm)
{
case fs_perm_read:
- return (*_stat_info).st_mode & S_IROTH;
+ return (*_imp->stat_info).st_mode & S_IROTH;
case fs_perm_write:
- return (*_stat_info).st_mode & S_IWOTH;
+ return (*_imp->stat_info).st_mode & S_IWOTH;
case fs_perm_execute:
- return (*_stat_info).st_mode & S_IXOTH;
+ return (*_imp->stat_info).st_mode & S_IXOTH;
}
throw InternalError(PALUDIS_HERE, "Unhandled FSPermission");
}
@@ -269,14 +291,14 @@ FSEntry::has_permission(const FSUserGroup & user_group, const FSPermission & fs_
mode_t
FSEntry::permissions() const
{
- Context context("When fetching permissions for '" + stringify(_path) + "':");
+ Context context("When fetching permissions for '" + stringify(_imp->path) + "':");
_stat();
- if (! _exists)
- throw FSError("Filesystem entry '" + _path + "' does not exist");
+ if (! _imp->exists)
+ throw FSError("Filesystem entry '" + _imp->path + "' does not exist");
- return _stat_info->st_mode;
+ return _imp->stat_info->st_mode;
}
void
@@ -284,34 +306,34 @@ FSEntry::_normalise()
{
try
{
- if (std::string::npos != _path.find("//"))
+ if (std::string::npos != _imp->path.find("//"))
{
std::string new_path;
std::string::size_type p(0);
- while (p < _path.length())
+ while (p < _imp->path.length())
{
- if ('/' == _path[p])
+ if ('/' == _imp->path[p])
{
new_path += '/';
- while (++p < _path.length())
- if ('/' != _path[p])
+ while (++p < _imp->path.length())
+ if ('/' != _imp->path[p])
break;
}
else
- new_path += _path[p++];
+ new_path += _imp->path[p++];
}
- _path = new_path;
+ _imp->path = new_path;
}
- if (! _path.empty())
- if ('/' == _path.at(_path.length() - 1))
- _path.erase(_path.length() - 1);
- if (_path.empty())
- _path = "/";
+ if (! _imp->path.empty())
+ if ('/' == _imp->path.at(_imp->path.length() - 1))
+ _imp->path.erase(_imp->path.length() - 1);
+ if (_imp->path.empty())
+ _imp->path = "/";
}
catch (const std::exception & e)
{
- Context c("When normalising FSEntry path '" + _path + "':");
+ Context c("When normalising FSEntry path '" + _imp->path + "':");
throw InternalError(PALUDIS_HERE,
"caught std::exception '" + stringify(e.what()) + "'");
}
@@ -320,34 +342,35 @@ FSEntry::_normalise()
void
FSEntry::_stat() const
{
- if (_checked)
+ Lock l(_imp->mutex);
+ if (_imp->checked)
return;
- Context context("When calling stat() on '" + stringify(_path) + "':");
+ Context context("When calling stat() on '" + stringify(_imp->path) + "':");
- _stat_info.reset(new struct stat);
- if (0 != lstat(_path.c_str(), _stat_info.get()))
+ _imp->stat_info.reset(new struct stat);
+ if (0 != lstat(_imp->path.c_str(), _imp->stat_info.get()))
{
if (errno != ENOENT)
- throw FSError("Error running stat() on '" + stringify(_path) + "': "
+ throw FSError("Error running stat() on '" + stringify(_imp->path) + "': "
+ strerror(errno));
- _exists = false;
- _stat_info.reset();
+ _imp->exists = false;
+ _imp->stat_info.reset();
}
else
- _exists = true;
+ _imp->exists = true;
- _checked = true;
+ _imp->checked = true;
}
std::string
FSEntry::basename() const
{
- if (_path == "/")
- return _path;
+ if (_imp->path == "/")
+ return _imp->path;
- return _path.substr(_path.rfind('/') + 1);
+ return _imp->path.substr(_imp->path.rfind('/') + 1);
}
FSEntry
@@ -357,29 +380,29 @@ FSEntry::strip_leading(const FSEntry & f) const
if (root == "/")
root.clear();
- if (0 != _path.compare(0, root.length(), root))
- throw FSError("Can't strip leading '" + root + "' from FSEntry '" + _path + "'");
- return FSEntry(_path.substr(root.length()));
+ if (0 != _imp->path.compare(0, root.length(), root))
+ throw FSError("Can't strip leading '" + root + "' from FSEntry '" + _imp->path + "'");
+ return FSEntry(_imp->path.substr(root.length()));
}
FSEntry
FSEntry::dirname() const
{
- if (_path == "/")
- return FSEntry(_path);
+ if (_imp->path == "/")
+ return FSEntry(_imp->path);
- return FSEntry(_path.substr(0, _path.rfind('/')));
+ return FSEntry(_imp->path.substr(0, _imp->path.rfind('/')));
}
FSEntry
FSEntry::realpath() const
{
- Context context("When fetching realpath of '" + stringify(_path) + "':");
+ Context context("When fetching realpath of '" + stringify(_imp->path) + "':");
#ifdef HAVE_CANONICALIZE_FILE_NAME
- char * r(canonicalize_file_name(_path.c_str()));
+ char * r(canonicalize_file_name(_imp->path.c_str()));
if (! r)
- throw FSError("Could not resolve path '" + _path + "'");
+ throw FSError("Could not resolve path '" + _imp->path + "'");
FSEntry result(r);
std::free(r);
return result;
@@ -387,12 +410,12 @@ FSEntry::realpath() const
char r[PATH_MAX + 1];
std::memset(r, 0, PATH_MAX + 1);
if (! exists())
- throw FSError("Could not resolve path '" + _path + "'");
- if (! ::realpath(_path.c_str(), r))
- throw FSError("Could not resolve path '" + _path + "'");
+ throw FSError("Could not resolve path '" + _imp->path + "'");
+ if (! ::realpath(_imp->path.c_str(), r))
+ throw FSError("Could not resolve path '" + _imp->path + "'");
FSEntry result(r);
if (! result.exists())
- throw FSError("Could not resolve path '" + _path + "'");
+ throw FSError("Could not resolve path '" + _imp->path + "'");
return result;
#endif
}
@@ -400,10 +423,10 @@ FSEntry::realpath() const
FSEntry
FSEntry::realpath_if_exists() const
{
- Context context("When fetching realpath of '" + stringify(_path) + "', if it exists:");
+ Context context("When fetching realpath of '" + stringify(_imp->path) + "', if it exists:");
#ifdef HAVE_CANONICALIZE_FILE_NAME
- char * r(canonicalize_file_name(_path.c_str()));
+ char * r(canonicalize_file_name(_imp->path.c_str()));
if (! r)
return *this;
FSEntry result(r);
@@ -414,7 +437,7 @@ FSEntry::realpath_if_exists() const
std::memset(r, 0, PATH_MAX + 1);
if (! exists())
return *this;
- if (! ::realpath(_path.c_str(), r))
+ if (! ::realpath(_imp->path.c_str(), r))
return *this;
FSEntry result(r);
if (! result.exists())
@@ -436,7 +459,7 @@ FSEntry::cwd()
std::ostream &
paludis::operator<< (std::ostream & s, const FSEntry & f)
{
- s << f._path;
+ s << f._imp->path;
return s;
}
@@ -445,10 +468,10 @@ FSEntry::ctime() const
{
_stat();
- if (! _exists)
- throw FSError("Filesystem entry '" + _path + "' does not exist");
+ if (! _imp->exists)
+ throw FSError("Filesystem entry '" + _imp->path + "' does not exist");
- return (*_stat_info).st_ctime;
+ return (*_imp->stat_info).st_ctime;
}
time_t
@@ -456,10 +479,10 @@ FSEntry::mtime() const
{
_stat();
- if (! _exists)
- throw FSError("Filesystem entry '" + _path + "' does not exist");
+ if (! _imp->exists)
+ throw FSError("Filesystem entry '" + _imp->path + "' does not exist");
- return (*_stat_info).st_mtime;
+ return (*_imp->stat_info).st_mtime;
}
off_t
@@ -467,19 +490,19 @@ FSEntry::file_size() const
{
_stat();
- if (! _exists)
- throw FSError("Filesystem entry '" + _path + "' does not exist");
+ if (! _imp->exists)
+ throw FSError("Filesystem entry '" + _imp->path + "' does not exist");
if (! is_regular_file())
- throw FSError("file_size called on non-regular file '" + _path + "'");
+ throw FSError("file_size called on non-regular file '" + _imp->path + "'");
- return _stat_info->st_size;
+ return _imp->stat_info->st_size;
}
bool
FSEntry::mkdir(mode_t mode)
{
- if (0 == ::mkdir(_path.c_str(), mode))
+ if (0 == ::mkdir(_imp->path.c_str(), mode))
return true;
int e(errno);
@@ -487,45 +510,45 @@ FSEntry::mkdir(mode_t mode)
{
if (is_directory())
return false;
- throw FSError("mkdir '" + _path + "' failed: target exists and is not a directory");
+ throw FSError("mkdir '" + _imp->path + "' failed: target exists and is not a directory");
}
else
- throw FSError("mkdir '" + _path + "' failed: " + ::strerror(e));
+ throw FSError("mkdir '" + _imp->path + "' failed: " + ::strerror(e));
}
bool
FSEntry::unlink()
{
#ifdef HAVE_LCHFLAGS
- if (0 != ::lchflags(_path.c_str(), 0))
+ if (0 != ::lchflags(_imp->path.c_str(), 0))
{
int e(errno);
if (e != ENOENT)
- throw FSError("lchflags for unlink '" + _path + "' failed: " + ::strerror(e));
+ throw FSError("lchflags for unlink '" + _imp->path + "' failed: " + ::strerror(e));
}
#endif
- if (0 == ::unlink(_path.c_str()))
+ if (0 == ::unlink(_imp->path.c_str()))
return true;
int e(errno);
if (e == ENOENT)
return false;
else
- throw FSError("unlink '" + _path + "' failed: " + ::strerror(e));
+ throw FSError("unlink '" + _imp->path + "' failed: " + ::strerror(e));
}
bool
FSEntry::rmdir()
{
- if (0 == ::rmdir(_path.c_str()))
+ if (0 == ::rmdir(_imp->path.c_str()))
return true;
int e(errno);
if (e == ENOENT)
return false;
else
- throw FSError("rmdir '" + _path + "' failed: " + ::strerror(e));
+ throw FSError("rmdir '" + _imp->path + "' failed: " + ::strerror(e));
}
std::string
@@ -533,24 +556,24 @@ FSEntry::readlink() const
{
char buf[PATH_MAX + 1];
std::memset(buf, 0, PATH_MAX + 1);
- if (-1 == ::readlink(_path.c_str(), buf, PATH_MAX))
- throw FSError("readlink '" + _path + "' failed: " + ::strerror(errno));
+ if (-1 == ::readlink(_imp->path.c_str(), buf, PATH_MAX))
+ throw FSError("readlink '" + _imp->path + "' failed: " + ::strerror(errno));
return buf;
}
void
FSEntry::chown(const uid_t new_owner, const gid_t new_group)
{
- if (0 != ::chown(_path.c_str(), new_owner, new_group))
- throw FSError("chown '" + _path + "' to '" + stringify(new_owner) + "', '"
+ if (0 != ::chown(_imp->path.c_str(), new_owner, new_group))
+ throw FSError("chown '" + _imp->path + "' to '" + stringify(new_owner) + "', '"
+ stringify(new_group) + "' failed: " + ::strerror(errno));
}
void
FSEntry::chmod(const mode_t mode)
{
- if (0 != ::chmod(_path.c_str(), mode))
- throw FSError("chmod '" + _path + "' failed: " + ::strerror(errno));
+ if (0 != ::chmod(_imp->path.c_str(), mode))
+ throw FSError("chmod '" + _imp->path + "' failed: " + ::strerror(errno));
}
uid_t
@@ -558,10 +581,10 @@ FSEntry::owner() const
{
_stat();
- if (! _exists)
- throw FSError("Filesystem entry '" + _path + "' does not exist");
+ if (! _imp->exists)
+ throw FSError("Filesystem entry '" + _imp->path + "' does not exist");
- return _stat_info->st_uid;
+ return _imp->stat_info->st_uid;
}
gid_t
@@ -569,17 +592,17 @@ FSEntry::group() const
{
_stat();
- if (! _exists)
- throw FSError("Filesystem entry '" + _path + "' does not exist");
+ if (! _imp->exists)
+ throw FSError("Filesystem entry '" + _imp->path + "' does not exist");
- return _stat_info->st_gid;
+ return _imp->stat_info->st_gid;
}
void
FSEntry::rename(const FSEntry & new_name)
{
- if (0 != ::rename(_path.c_str(), new_name._path.c_str()))
- throw FSError("rename('" + stringify(_path) + "', '" + stringify(new_name._path) + "') failed: " +
+ if (0 != ::rename(_imp->path.c_str(), new_name._imp->path.c_str()))
+ throw FSError("rename('" + stringify(_imp->path) + "', '" + stringify(new_name._imp->path) + "') failed: " +
::strerror(errno));
}
diff --git a/paludis/util/fs_entry.hh b/paludis/util/fs_entry.hh
index ce1957e..4720c08 100644
--- a/paludis/util/fs_entry.hh
+++ b/paludis/util/fs_entry.hh
@@ -24,6 +24,7 @@
#include <paludis/util/fs_entry-fwd.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/operators.hh>
+#include <paludis/util/private_implementation_pattern.hh>
#include <string>
#include <iosfwd>
#include <paludis/util/tr1_memory.hh>
@@ -64,22 +65,12 @@ namespace paludis
*/
class PALUDIS_VISIBLE FSEntry :
public relational_operators::HasRelationalOperators,
- public arithmetic_operators::HasArithmeticOperators
+ public arithmetic_operators::HasArithmeticOperators,
+ private PrivateImplementationPattern<FSEntry>
{
friend std::ostream & operator<< (std::ostream & s, const FSEntry & f);
private:
- std::string _path;
-
- mutable tr1::shared_ptr<struct ::stat> _stat_info;
-
- mutable bool _exists;
-
- /**
- * Whether or not we have run _stat() on this location yet
- */
- mutable bool _checked;
-
void _normalise();
/**
diff --git a/paludis/version_spec.cc b/paludis/version_spec.cc
index b12e7f8..f014e2b 100644
--- a/paludis/version_spec.cc
+++ b/paludis/version_spec.cc
@@ -25,6 +25,7 @@
#include <paludis/util/strip.hh>
#include <paludis/util/log.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/mutex.hh>
#include <paludis/version_spec.hh>
#include <vector>
#include <limits>
@@ -89,10 +90,12 @@ namespace paludis
std::vector<Part> parts;
/// Our hash
+ mutable Mutex hash_mutex;
mutable bool has_hash;
mutable std::size_t hash;
/// Our is_scm
+ mutable Mutex is_scm_mutex;
mutable bool has_is_scm;
mutable bool is_scm;
@@ -502,6 +505,8 @@ VersionSpec::equal_star_compare(const VersionSpec & other) const
std::size_t
VersionSpec::hash_value() const
{
+ Lock l(_imp->hash_mutex);
+
if (_imp->has_hash)
return _imp->hash;
@@ -622,6 +627,8 @@ paludis::operator<< (std::ostream & s, const VersionSpec & v)
bool
VersionSpec::is_scm() const
{
+ Lock l(_imp->is_scm_mutex);
+
if (_imp->has_is_scm)
return _imp->is_scm;