From da7a5f968470abd1a7bdccbb0b92ae081a5d33ce Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 13 Apr 2012 15:00:50 -0700 Subject: [PATCH] reference count the shape_featureset in a custom way (destructors are not called immediately from node.js) to watch for thread unsafe usage of the resource --- plugins/input/shape/shape_datasource.cpp | 9 ++++++--- plugins/input/shape/shape_datasource.hpp | 4 ++++ plugins/input/shape/shape_index_featureset.cpp | 14 +++++++++++--- plugins/input/shape/shape_index_featureset.hpp | 4 +++- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/plugins/input/shape/shape_datasource.cpp b/plugins/input/shape/shape_datasource.cpp index 5ceb23284..6e0217637 100644 --- a/plugins/input/shape/shape_datasource.cpp +++ b/plugins/input/shape/shape_datasource.cpp @@ -61,7 +61,8 @@ shape_datasource::shape_datasource(const parameters ¶ms, bool bind) file_length_(0), indexed_(false), row_limit_(*params_.get("row_limit",0)), - desc_(*params.get("type"), *params.get("encoding","utf-8")) + desc_(*params.get("type"), *params.get("encoding","utf-8")), + in_use_(0) { boost::optional file = params.get("file"); if (!file) throw datasource_exception("Shape Plugin: missing parameter"); @@ -273,7 +274,8 @@ featureset_ptr shape_datasource::features(const query& q) const q.property_names(), desc_.get_encoding(), shape_name_, - row_limit_)); + row_limit_, + in_use_)); } else { @@ -317,7 +319,8 @@ featureset_ptr shape_datasource::features_at_point(coord2d const& pt) const names, desc_.get_encoding(), shape_name_, - row_limit_)); + row_limit_, + in_use_)); } else { diff --git a/plugins/input/shape/shape_datasource.hpp b/plugins/input/shape/shape_datasource.hpp index 641f9e373..bfabdb5d1 100644 --- a/plugins/input/shape/shape_datasource.hpp +++ b/plugins/input/shape/shape_datasource.hpp @@ -65,6 +65,10 @@ private: mutable bool indexed_; const int row_limit_; mutable layer_descriptor desc_; + // shape_datasource should not be used between threads + // because for indexed files shape_ is kept open for speed + // since this condition is so hard to debug we'll track and warn + mutable int in_use_; }; #endif //SHAPE_HPP diff --git a/plugins/input/shape/shape_index_featureset.cpp b/plugins/input/shape/shape_index_featureset.cpp index 904c7290c..c8705b31c 100644 --- a/plugins/input/shape/shape_index_featureset.cpp +++ b/plugins/input/shape/shape_index_featureset.cpp @@ -43,14 +43,17 @@ shape_index_featureset::shape_index_featureset(filterT const& filter, std::set const& attribute_names, std::string const& encoding, std::string const& shape_name, - int row_limit) + int row_limit, + int & in_use) : filter_(filter), ctx_(boost::make_shared()), shape_(shape), tr_(new transcoder(encoding)), row_limit_(row_limit), - count_(0) + count_(0), + in_use_(in_use) { + in_use_++; shape_.shp().skip(100); setup_attributes(ctx_, attribute_names, shape_name, shape_,attr_ids_); @@ -75,8 +78,12 @@ shape_index_featureset::shape_index_featureset(filterT const& filter, template feature_ptr shape_index_featureset::next() { + if (in_use_ > 1) + MAPNIK_LOG_ERROR(shape) << "*** Warning: indexed shape_featureset appears to be being used by more than one thread\n"; + if (row_limit_ && count_ > row_limit_) { + in_use_--; return feature_ptr(); } @@ -135,6 +142,7 @@ feature_ptr shape_index_featureset::next() } else { + in_use_--; return feature_ptr(); } } @@ -201,7 +209,7 @@ feature_ptr shape_index_featureset::next() else { MAPNIK_LOG_DEBUG(shape) << "shape_index_featureset: " << count_ << " features"; - + in_use_--; return feature_ptr(); } } diff --git a/plugins/input/shape/shape_index_featureset.hpp b/plugins/input/shape/shape_index_featureset.hpp index 410a10358..726456761 100644 --- a/plugins/input/shape/shape_index_featureset.hpp +++ b/plugins/input/shape/shape_index_featureset.hpp @@ -51,7 +51,8 @@ public: std::set const& attribute_names, std::string const& encoding, std::string const& shape_name, - int row_limit); + int row_limit, + int & in_use); virtual ~shape_index_featureset(); feature_ptr next(); @@ -65,6 +66,7 @@ private: std::vector attr_ids_; const int row_limit_; mutable int count_; + int & in_use_; }; #endif // SHAPE_INDEX_FEATURESET_HPP