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
This commit is contained in:
parent
5767c65470
commit
da7a5f9684
4 changed files with 24 additions and 7 deletions
|
@ -61,7 +61,8 @@ shape_datasource::shape_datasource(const parameters ¶ms, bool bind)
|
|||
file_length_(0),
|
||||
indexed_(false),
|
||||
row_limit_(*params_.get<int>("row_limit",0)),
|
||||
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8"))
|
||||
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8")),
|
||||
in_use_(0)
|
||||
{
|
||||
boost::optional<std::string> file = params.get<std::string>("file");
|
||||
if (!file) throw datasource_exception("Shape Plugin: missing <file> 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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -43,14 +43,17 @@ shape_index_featureset<filterT>::shape_index_featureset(filterT const& filter,
|
|||
std::set<std::string> 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<mapnik::context_type>()),
|
||||
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<filterT>::shape_index_featureset(filterT const& filter,
|
|||
template <typename filterT>
|
||||
feature_ptr shape_index_featureset<filterT>::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<filterT>::next()
|
|||
}
|
||||
else
|
||||
{
|
||||
in_use_--;
|
||||
return feature_ptr();
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +209,7 @@ feature_ptr shape_index_featureset<filterT>::next()
|
|||
else
|
||||
{
|
||||
MAPNIK_LOG_DEBUG(shape) << "shape_index_featureset: " << count_ << " features";
|
||||
|
||||
in_use_--;
|
||||
return feature_ptr();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,8 @@ public:
|
|||
std::set<std::string> 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<int> attr_ids_;
|
||||
const int row_limit_;
|
||||
mutable int count_;
|
||||
int & in_use_;
|
||||
};
|
||||
|
||||
#endif // SHAPE_INDEX_FEATURESET_HPP
|
||||
|
|
Loading…
Reference in a new issue