BIND 10 trac2051, updated. 3e81e7316c18dc68887db2b96c0b8c6ea438b684 [2051] Make sure results aren't deleted too soon
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Jul 17 13:09:29 UTC 2012
The branch, trac2051 has been updated
via 3e81e7316c18dc68887db2b96c0b8c6ea438b684 (commit)
from 77ac69b41cb54761744019e7e1935dbbd9b1cf32 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 3e81e7316c18dc68887db2b96c0b8c6ea438b684
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Jul 17 15:07:21 2012 +0200
[2051] Make sure results aren't deleted too soon
In the python part, we play a little with the reference counts. The data
source client wrapper can now hold a life keeper in addition to the
container, as some data source clients don't come from the container or
are not known.
-----------------------------------------------------------------------
Summary of changes:
src/lib/python/isc/datasrc/client_python.cc | 23 ++++++++++++++++----
src/lib/python/isc/datasrc/client_python.h | 8 ++++++-
.../isc/datasrc/configurableclientlist_python.cc | 13 +++++++++--
.../python/isc/datasrc/tests/clientlist_test.py | 7 ++++++
4 files changed, 44 insertions(+), 7 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/python/isc/datasrc/client_python.cc b/src/lib/python/isc/datasrc/client_python.cc
index 7754d79..1a9ae47 100644
--- a/src/lib/python/isc/datasrc/client_python.cc
+++ b/src/lib/python/isc/datasrc/client_python.cc
@@ -28,6 +28,7 @@
#include <datasrc/data_source.h>
#include <datasrc/sqlite3_accessor.h>
#include <datasrc/iterator.h>
+#include <datasrc/client_list.h>
#include <dns/python/name_python.h>
#include <dns/python/rrset_python.h>
@@ -53,10 +54,15 @@ class s_DataSourceClient : public PyObject {
public:
s_DataSourceClient() :
cppobj(NULL),
- client(NULL)
+ client(NULL),
+ keeper(NULL)
{};
DataSourceClientContainer* cppobj;
DataSourceClient* client;
+ // We can't rely on the constructor or destructor being
+ // called, so this is a pointer to shared pointer, so we
+ // can call the new and delete explicitly.
+ boost::shared_ptr<ClientList::FindResult::LifeKeeper>* keeper;
};
PyObject*
@@ -250,6 +256,7 @@ DataSourceClient_init(PyObject* po_self, PyObject* args, PyObject*) {
self->cppobj = new DataSourceClientContainer(ds_type_str,
ds_config);
self->client = &self->cppobj->getInstance();
+ self->keeper = NULL;
return (0);
} else {
return (-1);
@@ -285,8 +292,10 @@ void
DataSourceClient_destroy(PyObject* po_self) {
s_DataSourceClient* const self = static_cast<s_DataSourceClient*>(po_self);
delete self->cppobj;
+ delete self->keeper;
self->cppobj = NULL;
self->client = NULL;
+ self->keeper = NULL;
Py_TYPE(self)->tp_free(self);
}
@@ -349,14 +358,20 @@ PyTypeObject datasourceclient_type = {
};
PyObject*
-wrapDataSourceClient(DataSourceClient* client) {
- // There aro no exceptions here, so this is safe
+wrapDataSourceClient(DataSourceClient* client,
+ const boost::shared_ptr<ClientList::FindResult::
+ LifeKeeper>& life_keeper)
+{
s_DataSourceClient *result =
static_cast<s_DataSourceClient*>(PyObject_New(s_DataSourceClient,
&datasourceclient_type));
+ CPPPyObjectContainer<s_DataSourceClient, DataSourceClientContainer>
+ container(result);
result->cppobj = NULL;
+ result->keeper =
+ new boost::shared_ptr<ClientList::FindResult::LifeKeeper>(life_keeper);
result->client = client;
- return (result);
+ return (container.release());
}
} // namespace python
diff --git a/src/lib/python/isc/datasrc/client_python.h b/src/lib/python/isc/datasrc/client_python.h
index b30c0fb..55fd99a 100644
--- a/src/lib/python/isc/datasrc/client_python.h
+++ b/src/lib/python/isc/datasrc/client_python.h
@@ -15,6 +15,8 @@
#ifndef __PYTHON_DATASRC_CLIENT_H
#define __PYTHON_DATASRC_CLIENT_H 1
+#include <datasrc/client_list.h>
+
#include <Python.h>
namespace isc {
@@ -26,7 +28,11 @@ namespace python {
extern PyTypeObject datasourceclient_type;
// TODO: Documentation, warning
-PyObject* wrapDataSourceClient(DataSourceClient* client);
+PyObject*
+wrapDataSourceClient(DataSourceClient* client,
+ const boost::shared_ptr<ClientList::FindResult::
+ LifeKeeper>& life_keeper = boost::shared_ptr<ClientList::
+ FindResult::LifeKeeper>());
} // namespace python
} // namespace datasrc
diff --git a/src/lib/python/isc/datasrc/configurableclientlist_python.cc b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
index ddca636..6670966 100644
--- a/src/lib/python/isc/datasrc/configurableclientlist_python.cc
+++ b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
@@ -132,13 +132,22 @@ ConfigurableClientList_find(PyObject* po_self, PyObject* args) {
// reference counts correctly.
dsrc.reset(Py_BuildValue(""));
} else {
- dsrc.reset(wrapDataSourceClient(result.dsrc_client_));
+ // Make sure we have a keeper there too, so it doesn't
+ // die when the underlying client list dies or is
+ // reconfigured.
+ //
+ // However, as it is inside the C++ part, is there a
+ // reasonable way to test it?
+ dsrc.reset(wrapDataSourceClient(result.dsrc_client_,
+ result.life_keeper_));
}
PyObjectContainer finder;
if (result.finder_ == NULL) {
finder.reset(Py_BuildValue(""));
} else {
- finder.reset(createZoneFinderObject(result.finder_));
+ // Make sure it keeps the data source client alive.
+ finder.reset(createZoneFinderObject(result.finder_,
+ dsrc.get()));
}
PyObjectContainer exact(PyBool_FromLong(result.exact_match_));
diff --git a/src/lib/python/isc/datasrc/tests/clientlist_test.py b/src/lib/python/isc/datasrc/tests/clientlist_test.py
index 334042f..54b20e1 100644
--- a/src/lib/python/isc/datasrc/tests/clientlist_test.py
+++ b/src/lib/python/isc/datasrc/tests/clientlist_test.py
@@ -18,6 +18,7 @@ import isc.datasrc
import isc.dns
import unittest
import os
+import sys
TESTDATA_PATH = os.environ['GLOBAL_TESTDATA_PATH'] + os.sep
@@ -103,6 +104,12 @@ class ClientListTest(unittest.TestCase):
self.assertTrue(isinstance(dsrc, isc.datasrc.DataSourceClient))
self.assertIsNotNone(finder)
self.assertTrue(isinstance(finder, isc.datasrc.ZoneFinder))
+ # Check the finder holds a reference to the data source
+ # Note that one reference is kept in the parameter list
+ # of getrefcount
+ self.assertEqual(3, sys.getrefcount(dsrc))
+ finder = None
+ self.assertEqual(2, sys.getrefcount(dsrc))
# We check an exact match in test_configure already
self.assertFalse(exact)
dsrc, finder, exact = clist.find(isc.dns.Name("sub.example.org"),
More information about the bind10-changes
mailing list