Author: aconway
Date: Tue Dec 16 15:29:27 2014
New Revision: 1645976

URL: http://svn.apache.org/r1645976
Log:
DISPATCH-87: Double load of libqpid-dispatch.so

We use ctypes to call from python into the qpid-dispatch.so library.
In some situations (running a build exe where there was an installed dispatch),
the exe could open the build library but ctypes could open the installed library
causing mayhem and core dumps.

Fixed the code to use dlopen(RTLD_NOLOAD) in C to get a handle to the library 
loaded by C,
and then use the handle rather than the library name to open the library in 
ctypes
which ensures the same library.

NOTE: When running qdrouterd from a build you still need to use the right
environment (config.sh) to pick up the correct python libraries (correct
PYTHONPATH and internal libraries) or things will still go wrong.

Removed:
    qpid/dispatch/trunk/router/src/config.h.in
Modified:
    qpid/dispatch/trunk/CMakeLists.txt
    qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py
    qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py
    qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py
    qpid/dispatch/trunk/router/CMakeLists.txt
    qpid/dispatch/trunk/src/CMakeLists.txt
    qpid/dispatch/trunk/src/dispatch.c

Modified: qpid/dispatch/trunk/CMakeLists.txt
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/CMakeLists.txt?rev=1645976&r1=1645975&r2=1645976&view=diff
==============================================================================
--- qpid/dispatch/trunk/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/CMakeLists.txt Tue Dec 16 15:29:27 2014
@@ -82,6 +82,7 @@ set(QPID_DISPATCH_CONFDIR ${SYSCONF_INST
 ##
 find_library(proton_lib qpid-proton)
 find_library(pthread_lib pthread)
+find_library(dl_lib dl)
 find_library(rt_lib rt)
 find_path(proton_include proton/driver.h)
 

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py?rev=1645976&r1=1645975&r2=1645976&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py Tue Dec 16 
15:29:27 2014
@@ -34,17 +34,8 @@ class QdDll(ctypes.PyDLL):
     NOTE: We use the python calling convention because the C library
     internally makes python calls.
     """
-    _instance = None
-    @classmethod
-    def instance(cls):
-        if not cls._instance:
-            cls._instance = QdDll()
-        return cls._instance
-
-    def __init__(self):
-        lib = qpid_dispatch_site.LIB
-        assert lib
-        super(QdDll, self).__init__(lib)
+    def __init__(self, handle):
+        super(QdDll, self).__init__("qpid-dispatch", handle=handle)
 
         # Types
         self.qd_dispatch_p = ctypes.c_void_p
@@ -86,6 +77,3 @@ class QdDll(ctypes.PyDLL):
 
     def function(self, fname, restype, argtypes, check=True):
         return self._prototype(getattr(self, fname), restype, argtypes, check)
-
-def instance():
-    return QdDll.instance()

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py?rev=1645976&r1=1645975&r2=1645976&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py 
(original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py Tue 
Dec 16 15:29:27 2014
@@ -356,8 +356,8 @@ class EntityCache(object):
 class Agent(object):
     """AMQP managment agent"""
 
-    def __init__(self, dispatch):
-        self.qd = dispatch_c.instance()
+    def __init__(self, dispatch, qd):
+        self.qd = qd
         self.dispatch = dispatch
         self.schema = QdSchema()
         self.entities = EntityCache(self)

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py?rev=1645976&r1=1645975&r2=1645976&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py 
(original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py Tue 
Dec 16 15:29:27 2014
@@ -148,15 +148,15 @@ class Config(object):
         self.entities.remove(entity)
 
 
-def configure_dispatch(dispatch, filename):
+def configure_dispatch(dispatch, lib_handle, filename):
     """Called by C router code to load configuration file and do 
configuration"""
-    qd = dispatch_c.instance()
+    qd = dispatch_c.QdDll(lib_handle)
     dispatch = qd.qd_dispatch_p(dispatch)
     config = Config(filename)
 
     # NOTE: Can't import agent till till dispatch C extension module is 
initialized.
     from .agent import Agent
-    agent = Agent(dispatch)
+    agent = Agent(dispatch, qd)
     qd.qd_dispatch_set_agent(dispatch, agent)
 
     def configure(attributes):

Modified: qpid/dispatch/trunk/router/CMakeLists.txt
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/router/CMakeLists.txt?rev=1645976&r1=1645975&r2=1645976&view=diff
==============================================================================
--- qpid/dispatch/trunk/router/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/router/CMakeLists.txt Tue Dec 16 15:29:27 2014
@@ -20,7 +20,6 @@
 
 set(DEFAULT_CONFIG_PATH "${QPID_DISPATCH_CONFDIR}/qdrouterd.conf" CACHE string 
"Default config file path")
 set(DEFAULT_DISPATCH_PYTHON_DIR ${QPID_DISPATCH_PYTHON_DIR})
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in 
${CMAKE_CURRENT_BINARY_DIR}/config.h)
 
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 

Modified: qpid/dispatch/trunk/src/CMakeLists.txt
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/CMakeLists.txt?rev=1645976&r1=1645975&r2=1645976&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/src/CMakeLists.txt Tue Dec 16 15:29:27 2014
@@ -17,6 +17,8 @@
 ## under the License.
 ##
 
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in 
${CMAKE_CURRENT_BINARY_DIR}/config.h)
+
 # Generate code from the management schema.
 set(GENERATED_SOURCES
   schema_enum.h
@@ -74,7 +76,7 @@ set_property(
   )
 
 add_library(qpid-dispatch SHARED ${qpid_dispatch_SOURCES})
-target_link_libraries(qpid-dispatch ${proton_lib} ${pthread_lib} ${rt_lib} 
${PYTHON_LIBRARIES})
+target_link_libraries(qpid-dispatch ${proton_lib} ${pthread_lib} ${rt_lib} 
${dl_lib} ${PYTHON_LIBRARIES})
 set_target_properties(qpid-dispatch PROPERTIES
   VERSION "${SO_VERSION}"
   SOVERSION "${SO_VERSION_MAJOR}"
@@ -83,5 +85,6 @@ set_target_properties(qpid-dispatch PROP
 install(TARGETS qpid-dispatch
   LIBRARY DESTINATION ${LIB_INSTALL_DIR})
 
-# TODO aconway 2014-09-24: won't work on windows, need portable way to get 
link name.
-set (QPID_DISPATCH_LIB "libqpid-dispatch.so.${SO_VERSION_MAJOR}" PARENT_SCOPE)
+set (QPID_DISPATCH_LIB "libqpid-dispatch.so.${SO_VERSION_MAJOR}")
+
+

Modified: qpid/dispatch/trunk/src/dispatch.c
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/dispatch.c?rev=1645976&r1=1645975&r2=1645976&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/dispatch.c (original)
+++ qpid/dispatch/trunk/src/dispatch.c Tue Dec 16 15:29:27 2014
@@ -24,6 +24,7 @@
 #include <qpid/dispatch/ctools.h>
 #include <qpid/dispatch/static_assert.h>
 
+#include "config.h"
 #include "dispatch_private.h"
 #include "alloc_private.h"
 #include "log_private.h"
@@ -32,6 +33,7 @@
 #include "message_private.h"
 #include "entity.h"
 #include "entity_cache.h"
+#include <dlfcn.h>
 
 /**
  * Private Function Prototypes
@@ -74,11 +76,15 @@ STATIC_ASSERT(sizeof(long) >= sizeof(voi
 
 qd_error_t qd_dispatch_load_config(qd_dispatch_t *qd, const char *config_path)
 {
+    void *handle = dlopen(QPID_DISPATCH_LIB, RTLD_LAZY | RTLD_NOLOAD);
+    if (!handle)
+        return qd_error(QD_ERROR_RUNTIME, "Cannot locate library %s", 
QPID_DISPATCH_LIB);
+
     qd_python_lock_state_t lock_state = qd_python_lock();
     PyObject *module = 
PyImport_ImportModule("qpid_dispatch_internal.management.config");
     PyObject *configure_dispatch = module ? PyObject_GetAttrString(module, 
"configure_dispatch") : NULL;
     Py_XDECREF(module);
-    PyObject *result = configure_dispatch ? 
PyObject_CallFunction(configure_dispatch, "(ls)", (long)qd, config_path) : NULL;
+    PyObject *result = configure_dispatch ? 
PyObject_CallFunction(configure_dispatch, "(lls)", (long)qd, handle, 
config_path) : NULL;
     Py_XDECREF(configure_dispatch);
     if (!result) qd_error_py();
     Py_XDECREF(result);



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to