Merge pull request #1764 from strk/master_connection_leaks
Fix postgresql connection leaks
This commit is contained in:
commit
a20cf31c01
3 changed files with 35 additions and 14 deletions
|
@ -143,7 +143,7 @@ public:
|
||||||
|
|
||||||
bool isOK() const
|
bool isOK() const
|
||||||
{
|
{
|
||||||
return (PQstatus(conn_) != CONNECTION_BAD);
|
return (!closed_) && (PQstatus(conn_) != CONNECTION_BAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void close()
|
void close()
|
||||||
|
|
|
@ -113,10 +113,12 @@ postgis_datasource::postgis_datasource(parameters const& params)
|
||||||
if (pool)
|
if (pool)
|
||||||
{
|
{
|
||||||
shared_ptr<Connection> conn = pool->borrowObject();
|
shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
if (conn && conn->isOK())
|
if (!conn) return;
|
||||||
{
|
|
||||||
PoolGuard<shared_ptr<Connection>,
|
PoolGuard<shared_ptr<Connection>,
|
||||||
shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
||||||
|
if (conn->isOK())
|
||||||
|
{
|
||||||
|
|
||||||
desc_.set_encoding(conn->client_encoding());
|
desc_.set_encoding(conn->client_encoding());
|
||||||
|
|
||||||
|
@ -429,6 +431,7 @@ postgis_datasource::~postgis_datasource()
|
||||||
if (conn)
|
if (conn)
|
||||||
{
|
{
|
||||||
conn->close();
|
conn->close();
|
||||||
|
pool->returnObject(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -693,6 +696,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
||||||
if (conn)
|
if (conn)
|
||||||
{
|
{
|
||||||
err_msg += conn->status();
|
err_msg += conn->status();
|
||||||
|
pool->returnObject(conn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -714,10 +718,11 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t
|
||||||
if (pool)
|
if (pool)
|
||||||
{
|
{
|
||||||
shared_ptr<Connection> conn = pool->borrowObject();
|
shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
if (conn && conn->isOK())
|
if (!conn) return featureset_ptr();
|
||||||
{
|
|
||||||
PoolGuard<shared_ptr<Connection>, shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
PoolGuard<shared_ptr<Connection>, shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
||||||
|
|
||||||
|
if (conn->isOK())
|
||||||
|
{
|
||||||
if (geometryColumn_.empty())
|
if (geometryColumn_.empty())
|
||||||
{
|
{
|
||||||
std::ostringstream s_error;
|
std::ostringstream s_error;
|
||||||
|
@ -798,10 +803,10 @@ box2d<double> postgis_datasource::envelope() const
|
||||||
if (pool)
|
if (pool)
|
||||||
{
|
{
|
||||||
shared_ptr<Connection> conn = pool->borrowObject();
|
shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
if (conn && conn->isOK())
|
if (!conn) return extent_;
|
||||||
{
|
|
||||||
PoolGuard<shared_ptr<Connection>, shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
PoolGuard<shared_ptr<Connection>, shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
||||||
|
if (conn->isOK())
|
||||||
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
|
|
||||||
if (geometryColumn_.empty())
|
if (geometryColumn_.empty())
|
||||||
|
@ -890,10 +895,10 @@ boost::optional<mapnik::datasource::geometry_t> postgis_datasource::get_geometry
|
||||||
if (pool)
|
if (pool)
|
||||||
{
|
{
|
||||||
shared_ptr<Connection> conn = pool->borrowObject();
|
shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
if (conn && conn->isOK())
|
if (!conn) return result;
|
||||||
{
|
|
||||||
PoolGuard<shared_ptr<Connection>, shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
PoolGuard<shared_ptr<Connection>, shared_ptr< Pool<Connection,ConnectionCreator> > > guard(conn, pool);
|
||||||
|
if (conn->isOK())
|
||||||
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
std::string g_type;
|
std::string g_type;
|
||||||
try
|
try
|
||||||
|
|
|
@ -495,6 +495,22 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
|
||||||
eq_(feat['gid'],2)
|
eq_(feat['gid'],2)
|
||||||
eq_(feat['int_field'],922337203685477580)
|
eq_(feat['int_field'],922337203685477580)
|
||||||
|
|
||||||
|
def test_persist_connection_off():
|
||||||
|
# NOTE: max_size should be equal or greater than
|
||||||
|
# the pool size. There's currently no API to
|
||||||
|
# check nor set that size, but the current
|
||||||
|
# default is 20, so we use that value. See
|
||||||
|
# http://github.com/mapnik/mapnik/issues/863
|
||||||
|
max_size = 20
|
||||||
|
for i in range(0, max_size+1):
|
||||||
|
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,
|
||||||
|
max_size=1, # unused
|
||||||
|
persist_connection=False,
|
||||||
|
table='(select ST_MakePoint(0,0) as g, pg_backend_pid() as p, 1 as v) as w',
|
||||||
|
geometry_field='g')
|
||||||
|
fs = ds.featureset()
|
||||||
|
eq_(fs.next()['v'], 1)
|
||||||
|
|
||||||
atexit.register(postgis_takedown)
|
atexit.register(postgis_takedown)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in a new issue