[lmiwbem] fix deadlocks related to Python's GIL

Peter Hatina phatina at fedoraproject.org
Wed Jul 9 08:05:47 UTC 2014


commit 18ba73dff1b52e07d6be415580b16b42d4e09786
Author: Peter Hatina <phatina at redhat.com>
Date:   Wed Jul 9 09:17:15 2014 +0200

    fix deadlocks related to Python's GIL

 lmiwbem-04-fix-gil-deadlocks.patch |  294 ++++++++++++++++++++++++++++++++++++
 lmiwbem.spec                       |    7 +-
 2 files changed, 300 insertions(+), 1 deletions(-)
---
diff --git a/lmiwbem-04-fix-gil-deadlocks.patch b/lmiwbem-04-fix-gil-deadlocks.patch
new file mode 100644
index 0000000..c268c0c
--- /dev/null
+++ b/lmiwbem-04-fix-gil-deadlocks.patch
@@ -0,0 +1,294 @@
+diff --git a/src/lmiwbem_client.cpp b/src/lmiwbem_client.cpp
+index e9a2549..9b94774 100644
+--- a/src/lmiwbem_client.cpp
++++ b/src/lmiwbem_client.cpp
+@@ -48,6 +48,7 @@ void CIMClient::connect(
+         return;
+     }
+ 
++    ScopedMutex sm(m_mutex);
+     if (!m_addr_info.isHttps()) {
+         Pegasus::CIMClient::connect(
+             m_addr_info.hostname(),
+@@ -77,16 +78,24 @@ void CIMClient::connect(
+ 
+ void CIMClient::connectLocally()
+ {
++    ScopedMutex sm(m_mutex);
+     Pegasus::CIMClient::connectLocal();
+     m_is_connected = true;
+ }
+ 
+ void CIMClient::disconnect()
+ {
++    ScopedMutex sm(m_mutex);
+     Pegasus::CIMClient::disconnect();
+     m_is_connected = false;
+ }
+ 
++bool CIMClient::isConnected()
++{
++    ScopedMutex sm(m_mutex);
++    return m_is_connected;
++}
++
+ #ifdef HAVE_PEGASUS_VERIFICATION_CALLBACK_WITH_DATA
+ bool CIMClient::matchPattern(const Pegasus::String &pattern, const Pegasus::String &str)
+ {
+diff --git a/src/lmiwbem_client.h b/src/lmiwbem_client.h
+index 09e02c9..c925f15 100644
+--- a/src/lmiwbem_client.h
++++ b/src/lmiwbem_client.h
+@@ -27,6 +27,7 @@
+ #include <Pegasus/Common/CIMType.h>
+ #include <Pegasus/Common/SSLContext.h>
+ #include "lmiwbem_addr.h"
++#include "lmiwbem_mutex.h"
+ 
+ class CIMClient: public Pegasus::CIMClient
+ {
+@@ -42,7 +43,7 @@ public:
+         const Pegasus::String &trust_store);
+     void connectLocally();
+     void disconnect();
+-    bool isConnected() const { return m_is_connected; }
++    bool isConnected();
+ 
+     void setVerifyCertificate(bool verify = true) { m_verify_cert = verify; }
+     bool getVerifyCertificate() const { return m_verify_cert; }
+@@ -66,6 +67,7 @@ private:
+ #  endif // HAVE_PEGASUS_VERIFICATION_CALLBACK_WITH_DATA
+ 
+     Address m_addr_info;
++    Mutex m_mutex;
+     bool m_is_connected;
+     bool m_verify_cert;
+ };
+diff --git a/src/lmiwbem_connection.cpp b/src/lmiwbem_connection.cpp
+index 25f10f5..b53caba 100644
+--- a/src/lmiwbem_connection.cpp
++++ b/src/lmiwbem_connection.cpp
+@@ -92,7 +92,6 @@ WBEMConnection::WBEMConnection(
+     , m_key_file()
+     , m_default_namespace(CIMConstants::defaultNamespace())
+     , m_client()
+-    , m_mutex()
+ {
+     m_connect_locally = lmi::extract_or_throw<bool>(
+         connect_locally, "connect_locally");
+@@ -726,7 +725,6 @@ bp::object WBEMConnection::createInstance(const bp::object &instance)
+     Pegasus::CIMObjectPath new_inst_name;
+     Pegasus::CIMNamespaceName new_inst_name_ns(std_ns.c_str());
+     try {
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         new_inst_name = m_client.createInstance(
+             new_inst_name_ns,
+@@ -755,7 +753,6 @@ void WBEMConnection::deleteInstance(const bp::object &object_path)
+         std_ns = cim_path.getNameSpace().getString().getCString();
+ 
+     try {
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         m_client.deleteInstance(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -780,7 +777,6 @@ void WBEMConnection::modifyInstance(
+             ListConv::asPegasusPropertyList(property_list,
+             "PropertyList"));
+ 
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         m_client.modifyInstance(
+             Pegasus::CIMNamespaceName(inst_name.getNamespace().c_str()),
+@@ -812,7 +808,6 @@ bp::list WBEMConnection::enumerateInstances(
+             ListConv::asPegasusPropertyList(property_list,
+             "PropertyList"));
+ 
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_instances = m_client.enumerateInstances(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -847,7 +842,6 @@ bp::list WBEMConnection::enumerateInstanceNames(
+ 
+     Pegasus::Array<Pegasus::CIMObjectPath> cim_instance_names;
+     try {
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_instance_names = m_client.enumerateInstanceNames(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -901,7 +895,6 @@ bp::tuple WBEMConnection::invokeMethod(
+     }
+ 
+     try {
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_rval = m_client.invokeMethod(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -948,7 +941,6 @@ bp::object WBEMConnection::getInstance(
+             ListConv::asPegasusPropertyList(property_list, "PropertyList"));
+         Pegasus::CIMObjectPath cim_object_path = cim_instance_name.asPegasusCIMObjectPath();
+ 
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_instance = m_client.getInstance(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -988,7 +980,6 @@ bp::list WBEMConnection::enumerateClasses(
+ 
+     Pegasus::Array<Pegasus::CIMClass> cim_classes;
+     try {
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_classes = m_client.enumerateClasses(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -1026,7 +1017,6 @@ bp::list WBEMConnection::enumerateClassNames(
+ 
+     Pegasus::Array<Pegasus::CIMName> cim_classnames;
+     try {
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_classnames = m_client.enumerateClassNames(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -1058,7 +1048,6 @@ bp::list WBEMConnection::execQuery(
+ 
+     Pegasus::Array<Pegasus::CIMObject> cim_instances;
+     try {
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_instances = m_client.execQuery(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -1095,7 +1084,6 @@ bp::object WBEMConnection::getClass(
+             ListConv::asPegasusPropertyList(property_list,
+             "PropertyList"));
+ 
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_class = m_client.getClass(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -1162,7 +1150,6 @@ bp::list WBEMConnection::getAssociators(
+         if (!std_result_role.empty())
+             cim_result_role = std_result_role.c_str();
+ 
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_associators = m_client.associators(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -1230,7 +1217,6 @@ bp::list WBEMConnection::getAssociatorNames(
+         if (!std_result_role.empty())
+             cim_result_role = std_result_role.c_str();
+ 
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_associator_names = m_client.associatorNames(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -1287,7 +1273,6 @@ bp::list WBEMConnection::getReferences(
+         if (!std_role.empty())
+             cim_role = Pegasus::String(std_role.c_str());
+ 
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_references = m_client.references(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+@@ -1338,7 +1323,6 @@ bp::list WBEMConnection::getReferenceNames(
+         if (!std_role.empty())
+             cim_role = Pegasus::String(std_role.c_str());
+ 
+-        ScopedMutex sm(m_mutex);
+         ScopedConnection sc(this);
+         cim_reference_names = m_client.referenceNames(
+             Pegasus::CIMNamespaceName(std_ns.c_str()),
+diff --git a/src/lmiwbem_connection.h b/src/lmiwbem_connection.h
+index c13aabb..9c03062 100644
+--- a/src/lmiwbem_connection.h
++++ b/src/lmiwbem_connection.h
+@@ -26,7 +26,6 @@
+ #include "lmiwbem.h"
+ #include "lmiwbem_cimbase.h"
+ #include "lmiwbem_client.h"
+-#include "lmiwbem_mutex.h"
+ 
+ BOOST_PYTHON_BEGIN
+     class dict;
+@@ -76,7 +75,7 @@ public:
+         const bp::object &no_verification);
+     void connectLocally();
+     void disconnect();
+-    bool isConnected() const { return m_client.isConnected(); }
++    bool isConnected() { return m_client.isConnected(); }
+     std::string getHostname() const { return m_client.hostname(); }
+ 
+     bool getVerifyCertificate() { return !m_client.getVerifyCertificate(); }
+@@ -189,7 +188,6 @@ protected:
+     std::string m_key_file;
+     std::string m_default_namespace;
+     CIMClient m_client;
+-    Mutex m_mutex;
+ };
+ 
+ #endif // LMIWBEM_CONNECTION_H
+diff --git a/src/lmiwbem_mutex.h b/src/lmiwbem_mutex.h
+index 94ed3ed..d3d52d3 100644
+--- a/src/lmiwbem_mutex.h
++++ b/src/lmiwbem_mutex.h
+@@ -29,13 +29,47 @@ extern "C" {
+ class Mutex
+ {
+ public:
+-    Mutex() { pthread_mutex_init(&m_mutex, NULL); }
+-    ~Mutex() { pthread_mutex_destroy(&m_mutex); }
++    Mutex()
++        : m_good(false)
++        , m_locked(false)
++    {
++        m_good = pthread_mutex_init(&m_mutex, NULL) == 0;
++    }
+ 
+-    bool lock()   { return pthread_mutex_lock(&m_mutex) == 0; }
+-    bool unlock() { return pthread_mutex_unlock(&m_mutex) == 0; }
++    ~Mutex()
++    {
++        pthread_mutex_destroy(&m_mutex);
++    }
++
++    bool lock()
++    {
++        // We can't lock the mutex, initialization failed.
++        if (!m_good)
++            return false;
++
++        if (pthread_mutex_lock(&m_mutex) == 0)
++            m_locked = true;
++
++        return m_locked;
++    }
++
++    bool unlock()
++    {
++        // We can't unlock the mutex, initialization failed.
++        if (!m_good)
++            return false;
++
++        if (pthread_mutex_unlock(&m_mutex) == 0)
++            m_locked = false;
++
++        return m_locked;
++    }
++
++    bool isLocked() const { return m_locked; }
+ 
+ private:
++    bool m_good;
++    bool m_locked;
+     pthread_mutex_t m_mutex;
+ };
+ 
+@@ -45,6 +79,10 @@ public:
+     ScopedMutex(Mutex &m): m_mutex(m) { m_mutex.lock(); }
+     ~ScopedMutex() { m_mutex.unlock(); }
+ 
++    bool lock()   { return m_mutex.lock(); }
++    bool unlock() { return m_mutex.unlock(); }
++    bool isLocked() const { return m_mutex.isLocked(); }
++
+ private:
+     Mutex &m_mutex;
+ };
diff --git a/lmiwbem.spec b/lmiwbem.spec
index 81da3f9..1baba53 100644
--- a/lmiwbem.spec
+++ b/lmiwbem.spec
@@ -1,6 +1,6 @@
 Name:           lmiwbem
 Version:        0.2.0
-Release:        7%{?dist}
+Release:        8%{?dist}
 Summary:        Python WBEM Client
 License:        LGPLv2+
 URL:            https://github.com/phatina/lmiwbem
@@ -8,6 +8,7 @@ Source0:        https://github.com/phatina/lmiwbem/releases/download/%{name}-%{v
 Patch0:         lmiwbem-01-get-instance-ns.patch
 Patch1:         lmiwbem-02-fix-value-type-deduction.patch
 Patch2:         lmiwbem-03-platform-support.patch
+Patch3:         lmiwbem-04-fix-gil-deadlocks.patch
 
 BuildRequires:  autoconf
 BuildRequires:  automake
@@ -38,6 +39,7 @@ Group:          Documentation
 %patch0 -p1 -b .get-instance-ns
 %patch1 -p1 -b .value-type-deduction
 %patch2 -p1 -b .platform-support
+%patch3 -p1 -b .fix-gil-deadlocks
 
 %build
 autoreconf -if
@@ -57,6 +59,9 @@ find %{buildroot} -name '*.la' | xargs rm -f
 %{_docdir}/%{name}-%{version}/html
 
 %changelog
+* Wed Jul  9 2014 Peter Hatina <phatina at redhat.com> - 0.2.0-8
+- fix deadlocks related to Python's GIL
+
 * Fri Jun 13 2014 Peter Hatina <phatina at redhat.com> - 0.2.0-7
 - fix build for s390(x)
 


More information about the scm-commits mailing list