Commit f29890ee authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[trac983] worked around the symbol sharing issue between multiple .so's.

there doesn't seem to be a simple and portable way to allow direct sharing,
so I chose to get access to the variables via the python interpretor.
parent b327d9aa
......@@ -10,7 +10,7 @@ pythondir = $(PYTHON_SITEPKG_DIR)/isc/acl
pyexec_LTLIBRARIES = acl.la dns.la
pyexecdir = $(PYTHON_SITEPKG_DIR)/isc/acl
acl_la_SOURCES = acl.h acl.cc
acl_la_SOURCES = acl.cc
acl_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
acl_la_LDFLAGS = $(PYTHON_LDFLAGS)
acl_la_CXXFLAGS = $(AM_CXXFLAGS) $(PYTHON_CXXFLAGS)
......@@ -31,7 +31,6 @@ acl_la_LIBADD += $(PYTHON_LIB)
dns_la_LDFLAGS += -module
dns_la_LIBADD = $(top_builddir)/src/lib/acl/libdnsacl.la
dns_la_LIBADD += acl.la
dns_la_LIBADD += $(PYTHON_LIB)
EXTRA_DIST = acl.py dns.py
......
......@@ -18,24 +18,22 @@
#include <acl/acl.h>
#include "acl.h"
using namespace isc::util::python;
using namespace isc::acl::python;
namespace isc {
namespace acl {
namespace python {
namespace {
// Commonly used Python exception objects. Right now the acl module consists
// of only one .cc file, so we hide them in an unnamed namespace. If and when
// we extend this module with multiple .cc files, we should move them to
// a named namespace, say isc::acl::python, and declare them in a separate
// header file.
PyObject* po_ACLError;
PyObject* po_LoaderError;
}
}
}
namespace {
PyModuleDef acl = {
{ PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
"isc.acl",
"isc.acl.acl",
"This module provides Python bindings for the C++ classes in the "
"isc::acl namespace",
-1,
......
......@@ -24,7 +24,7 @@
#include <acl/acl.h>
#include <acl/dns.h>
#include "acl.h"
#include "dns.h"
#include "dns_requestcontext_python.h"
#include "dns_requestacl_python.h"
......@@ -53,7 +53,7 @@ loadRequestACL(PyObject*, PyObject* args) {
}
return (py_acl);
} catch (const exception& ex) {
PyErr_SetString(isc::acl::python::po_LoaderError, ex.what());
PyErr_SetString(getACLException("LoaderError"), ex.what());
return (NULL);
} catch (...) {
PyErr_SetString(PyExc_SystemError, "Unexpected C++ exception");
......@@ -86,6 +86,32 @@ PyModuleDef dnsacl = {
};
} // end of unnamed namespace
namespace isc {
namespace acl {
namespace dns {
namespace python {
PyObject*
getACLException(const char* ex_name) {
PyObject* ex_obj = NULL;
PyObject* acl_module = PyImport_AddModule("isc.acl.acl");
if (acl_module != NULL) {
PyObject* acl_dict = PyModule_GetDict(acl_module);
if (acl_dict != NULL) {
ex_obj = PyDict_GetItemString(acl_dict, ex_name);
}
}
if (ex_obj == NULL) {
ex_obj = PyExc_RuntimeError;
}
return (ex_obj);
}
}
}
}
}
PyMODINIT_FUNC
PyInit_dns(void) {
PyObject* mod = PyModule_Create(&dnsacl);
......
......@@ -12,23 +12,40 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __PYTHON_ACL_H
#define __PYTHON_ACL_H 1
#ifndef __PYTHON_ACL_DNS_H
#define __PYTHON_ACL_DNS_H 1
#include <Python.h>
namespace isc {
namespace acl {
namespace dns {
namespace python {
extern PyObject* po_ACLError;
extern PyObject* po_LoaderError;
// Return a Python exception object of the given name (ex_name) defined in
// the isc.acl.acl loadable module.
//
// Since the acl module is a different binary image and is loaded separately
// from the dns module, it would be very tricky to directly access to
// C/C++ symbols defined in that module. So we get access to these object
// using the Python interpretor through this wrapper function.
//
// The __init__.py file should ensure isc.acl.acl has been loaded by the time
// whenever this function is called, and there shouldn't be no operation
// within this function that can fail (such as dynamic memory allocation),
// so this function should always succeed. Yet there may be an overlooked
// failure mode, perhaps due to a bug in the binding implementation, or
// due to invalid usage. As a last resort for such cases, this function
// returns PyExc_RuntimeError (a C binding of Python's RuntimeError) should
// it encounters an unexpected failure.
extern PyObject* getACLException(const char* ex_name);
} // namespace python
} // namespace dns
} // namespace acl
} // namespace isc
#endif // __PYTHON_ACL_H
#endif // __PYTHON_ACL_DNS_H
// Local Variables:
// mode: c++
......
......@@ -28,14 +28,13 @@
#include <acl/acl.h>
#include <acl/dns.h>
#include "acl.h"
#include "dns.h"
#include "dns_requestacl_python.h"
#include "dns_requestcontext_python.h"
using namespace std;
using namespace isc::util::python;
using namespace isc::acl;
using namespace isc::acl::python;
using namespace isc::acl::dns;
using namespace isc::acl::dns::python;
......@@ -60,7 +59,8 @@ s_RequestACL::s_RequestACL() {}
namespace {
int
RequestACL_init(PyObject*, PyObject*, PyObject*) {
PyErr_SetString(po_ACLError, "RequestACL cannot be directly constructed");
PyErr_SetString(getACLException("Error"),
"RequestACL cannot be directly constructed");
return (-1);
}
......@@ -84,7 +84,7 @@ RequestACL_execute(PyObject* po_self, PyObject* args) {
}
} catch (const exception& ex) {
const string ex_what = "Failed to execute ACL: " + string(ex.what());
PyErr_SetString(po_ACLError, ex_what.c_str());
PyErr_SetString(getACLException("Error"), ex_what.c_str());
} catch (...) {
PyErr_SetString(PyExc_RuntimeError,
"Unexpected exception in executing ACL");
......
......@@ -42,7 +42,7 @@
#include <acl/dns.h>
#include <acl/ip_check.h>
#include "acl.h"
#include "dns.h"
#include "dns_requestcontext_python.h"
using namespace std;
......@@ -51,7 +51,6 @@ using boost::lexical_cast;
using namespace isc;
using namespace isc::util::python;
using namespace isc::acl::dns;
using namespace isc::acl::python;
using namespace isc::acl::dns::python;
namespace isc {
......@@ -177,7 +176,7 @@ RequestContext_init(PyObject* po_self, PyObject* args, PyObject*) {
} catch (const exception& ex) {
const string ex_what = "Failed to construct RequestContext object: " +
string(ex.what());
PyErr_SetString(po_ACLError, ex_what.c_str());
PyErr_SetString(getACLException("Error"), ex_what.c_str());
return (-1);
} catch (...) {
PyErr_SetString(PyExc_RuntimeError,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment