We used Valgrind Helgrind (http://valgrind.org/docs/manual/hg-manual.html ) to check thread safety in our code written so far. Among the reports generated by Helgrind on the unit-test executables of multiple modules, we see many instances of possible deadlocks related to libCppMicroServices. These are situations in which two threads acquire the same two mutex locks, but in opposite orders, i.e., a scenario that can potentially lead to dead locks if the relative timing of the two threads is interleaved in an unfortunate way. There are many instances of this error (thousands), but the copied error message below, in blue, is a representative sample.
As you can see, one thread acquires the two locks in the order of 0xEB58B68 and 0xEB33860, but another thread acquires the locks in the opposite order.
Observed (incorrect) order is: acquisition of lock at 0xEB58B68
==21976== at 0x4C2BAF5: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==21976== by 0x860C804: us::ServiceReferenceBasePrivate::GetService(us::Module_) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bi
n/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x861ADBF: us::ModuleContext::GetService(us::ServiceReferenceBase const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/mat
lab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x432469: TestActivator::serviceProviderRegistered() (usModuleContext.h:615)
==21976== by 0x6CD5281: CppUnit::TestCaseMethodFunctor::operator()() const (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libcppunit-1.12.so.1.0.0)
==21976== by 0x6CCB07E: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libcppunit-1.12.so.1.0.0)
==21976== by 0x6CD23F9: CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libcppunit-1.12.so.1.0.0)
==21976== by 0x6CDB254: CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test_, std::string const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libcppunit-1.12.so.1.0.0)
==21976== by 0x6CD5001: CppUnit::TestCase::run(CppUnit::TestResult_) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libcppunit-1.12.so.1.0.0)
==21976== by 0x6CD55E2: CppUnit::TestComposite::doRunChildTests(CppUnit::TestResult_) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libcppunit-1.12.so.1.0.0)
==21976== by 0x6CD54F5: CppUnit::TestComposite::run(CppUnit::TestResult_) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libcppunit-1.12.so.1.0.0)
==21976== by 0x6CD55E2: CppUnit::TestComposite::doRunChildTests(CppUnit::TestResult_) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libcppunit-1.12.so.1.0.0)
==21976==
==21976== followed by a later acquisition of lock at 0xEB33860
==21976== at 0x4C2BAF5: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==21976== by 0x8613AC4: us::ServiceRegistry::Get(us::ModulePrivate_, std::string const&) const (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x861AD36: us::ModuleContext::GetServiceReference(std::string const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x65AD2E4: us::ServiceReferenceconnector::configuration::Configuration us::ModuleContext::GetServiceReferenceconnector::configuration::Configuration() (usModuleContext.h:534)
==21976== by 0x65AD38C: connector::us_common::Dependencyconnector::configuration::Configuration::get(us::ModuleContext_) (Utils.hpp:138)
==21976== by 0x65AE056: connector::us_common::ServiceConstructor1<connector::configuration::ConfigurationServiceProviderImpl, connector::us_common::Dependencyconnector::configuration::Configuration, connector::common::ConnectorLifecycle>::make(us::ModuleContext_) (Utils.hpp:540)
==21976== by 0x65AE143: connector::us_common::ServiceFactoryHelper<connector::us_common::ServiceConstructor1<connector::configuration::ConfigurationServiceProviderImpl, connector::us_common::Dependencyconnector::configuration::Configuration, connector::common::ConnectorLifecycle>, connector::us_common::MakeInterfaceMap1<connector::configuration::ConfigurationServiceProviderImpl, connector::ServiceProvider> >::GetService(us::Module_, us::ServiceRegistrationBase const&) (Utils.hpp:442)
==21976== by 0x860B326: us::ServiceReferenceBasePrivate::GetServiceFromFactory(us::Module_, us::ServiceFactory_, bool) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x860C896: us::ServiceReferenceBasePrivate::GetService(us::Module*) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x861ADBF: us::ModuleContext::GetService(us::ServiceReferenceBase const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x432469: TestActivator::serviceProviderRegistered() (usModuleContext.h:615)
==21976== by 0x6CD5281: CppUnit::TestCaseMethodFunctor::operator()() const (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libcppunit-1.12.so.1.0.0)
==21976== Required order was established by acquisition of lock at 0xEB33860
==21976== at 0x4C2BAF5: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==21976== by 0x8614297: us::ServiceRegistry::RegisterService(us::ModulePrivate_, std::map<std::string, void_, std::lessstd::string, std::allocator<std::pair<std::string const, void*> > > const&, std::unordered_map<std::string, us::Any, std::hashstd::string, std::equal_to<std::
string>, std::allocator<std::pair<std::string const, us::Any> > > const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x861ACB9: us::ModuleContext::RegisterService(std::map<std::string, void*, std::lessstd::string, std::allocator<std::pair<std::string const, void*> > > const&, std::unordered_map<std::string, us::Any, std::hashstd::string, std::equal_tostd::string, std::allocator<std::pair<std::string const, us::Any> > > const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so
.2.1.0)
==21976== by 0x65A865D: connector::us_common::Registration<connector::us_common::ServiceFactoryConstructor<connector::us_common::ServiceConstructor1<connector::configuration::ConfigurationServiceProviderImpl, connector::us_common::Dependencyconnector::configuration::Configuration, connector::common::ConnectorLifecycle>, connector::us_common::MakeInterfaceMap1connector::configuration::ConfigurationServiceProviderImpl,connector::ServiceProvider >, connector::us_common::MakeInterfaceMap1<us::ServiceFactory, connector::ServiceProvider> >::start(us::ModuleContext_) (Utils.hpp:412)
==21976== by 0x65A8D78: std::mem_fun1_t<void, connector::us_common::WatchableDependencyconnector::Connector, us::ServiceEvent>::operator()(connector::us_common::WatchableDependencyconnector::Connector_, us::ServiceEvent) const (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libmwconnectorconfigurationactivator.so)
==21976== by 0x65A8DD4: std::Function_handler<void ()(us::ServiceEvent const&), std::binder1st<std::mem_fun1_t<void, connector::us_common::WatchableDependencyconnector::Connector, us::ServiceEvent> > >::M_invoke(std::Any_data const&, us::ServiceEvent const&) (binders.h:120)
==21976== by 0x8601FBA: us::ServiceListeners::ServiceChanged(std::unordered_set<us::ServiceListenerEntry, std::hashus::ServiceListenerEntry, std::equal_tous::ServiceListenerEntry, std::allocatorus::ServiceListenerEntry >&, us::ServiceEvent const&, std::unordered_set<us::ServiceListenerEntry, std::hashus::ServiceListenerEntry, std::equal_tous::ServiceListenerEntry, std::allocatorus::ServiceListenerEntry >&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x86021D7: us::ServiceListeners::ServiceChanged(std::unordered_set<us::ServiceListenerEntry, std::hashus::ServiceListenerEntry, std::equal_tous::ServiceListenerEntry, std::allocatorus::ServiceListenerEntry >&, us::ServiceEvent const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x86146AB: us::ServiceRegistry::RegisterService(us::ModulePrivate, std::map<std::string, void, std::lessstd::string, std::allocator<std::pair<std::string const, void*> > > const&, std::unordered_map<std::string, us::Any, std::hashstd::string, std::equal_tostd::string, std::allocator<std::pair<std::string const, us::Any> > > const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x861ACB9: us::ModuleContext::RegisterService(std::map<std::string, void*, std::lessstd::string, std::allocator<std::pair<std::string const, void*> > > const&, std::unordered_map<std::string, us::Any, std::hashstd::string, std::equal_tostd::string, std::allocator<std::pair<std::string const, us::Any> > > const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x430B98: us::ServiceRegistration<connector::Connector, void, void> us::ModuleContext::RegisterServiceconnector::Connector(connector::Connector, std::unordered_map<std::string, us::Any, std::hashstd::string, std::equal_tostd::string, std::allocator<std::pair<std::string const, us::Any> > > const&) (usModuleContext.h:235)
==21976== by 0x43131D: TestActivator::setUp() (TestActivator.cpp:55)
==21976==
==21976== followed by a later acquisition of lock at 0xEB58B68
==21976== at 0x4C2BAF5: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==21976== by 0x86099A6: us::ServiceReferenceBase::GetProperty(std::string const&) const (in/mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x8609CC6: us::ServiceReferenceBase::operator<(us::ServiceReferenceBase const&) const (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x861555A: __gnu_cxx::_normal_iterator<us::ServiceRegistrationBase, std::vector<us::ServiceRegistrationBase, std::allocatorus::ServiceRegistrationBase > > std::lower_bound<__gnu_cxx::__normal_iterator<us::ServiceRegistrationBase*, std::vector<us::ServiceRegistrationBase, std::allocatorus::ServiceRegistrationBase > >, us::ServiceRegistrationBase>(__gnu_cxx::__normal_iterator<us::ServiceRegistrationBase*, std::vector<us::ServiceRegistrationBase, std::allocatorus::ServiceRegistrationBase > >, gnu_cxx::normal_iterator<us::ServiceRegistrationBase*, std::vector<us::ServiceRegistrationBase, std::allocatorus::ServiceRegistrationBase > >, us::ServiceRegistrationBase const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x861448C: us::ServiceRegistry::RegisterService(us::ModulePrivate, std::map<std::string, void, std::lessstd::string, std::allocator<std::pair<std::string const, void*> > > const&, std::unordered_map<std::string, us::Any, std::hashstd::string, std::equal_tostd::string, std::allocator<std::pair<std::string const, us::Any> > > const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x861ACB9: us::ModuleContext::RegisterService(std::map<std::string, void*, std::lessstd::string, std::allocator<std::pair<std::string const,void*> > > const&, std::unordered_map<std::string, us::Any, std::hashstd::string, std::equal_tostd::string, std::allocator<std::pair<std::string const, us::Any> > > const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x65A865D: connector::us_common::Registration<connector::us_common::ServiceFactoryConstructor<connector::us_common::ServiceConstructor1<connector::configuration::ConfigurationServiceProviderImpl, connector::us_common::Dependencyconnector::configuration::Configuration, connector::common::ConnectorLifecycle>, connector::us_common::MakeInterfaceMap1<connector::configuration::ConfigurationServiceProviderImpl, connector::ServiceProvider> >, connector::us_common::MakeInterfaceMap1<us::ServiceFactory, connector::ServiceProvider> >::start(us::ModuleContext) (Utils.hpp:412)
==21976== by 0x65A8D78: std::mem_fun1_t<void, connector::us_common::WatchableDependencyconnector::Connector, us::ServiceEvent>::operator()(connector::us_common::WatchableDependencyconnector::Connector, us::ServiceEvent) const (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libmwconnectorconfigurationactivator.so)
==21976== by 0x65A8DD4: std::_Function_handler<void ()(us::ServiceEvent const&), std::binder1st<std::mem_fun1_t<void, connector::us_common::WatchableDependencyconnector::Connector, us::ServiceEvent> > >::M_invoke(std::Any_data const&, us::ServiceEvent const&) (binders.h:120)
==21976== by 0x8601FBA: us::ServiceListeners::ServiceChanged(std::unordered_set<us::ServiceListenerEntry, std::hashus::ServiceListenerEntry, std::equal_tous::ServiceListenerEntry, std::allocatorus::ServiceListenerEntry >&, us::ServiceEvent const&, std::unordered_set<us::ServiceListenerEntry, std::hashus::ServiceListenerEntry, std::equal_tous::ServiceListenerEntry, std::allocatorus::ServiceListenerEntry >&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x86021D7: us::ServiceListeners::ServiceChanged(std::unordered_set<us::ServiceListenerEntry, std::hashus::ServiceListenerEntry, std::equal_tous::ServiceListenerEntry, std::allocatorus::ServiceListenerEntry >&, us::ServiceEvent const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)
==21976== by 0x86146AB: us::ServiceRegistry::RegisterService(us::ModulePrivate, std::map<std::string, void, std::lessstd::string, std::allocator<std::pair<std::string const, void*> > > const&, std::unordered_map<std::string, us::Any, std::hashstd::string, std::equal_tostd::string, std::allocator<std::pair<std::string const, us::Any> > > const&) (in /mathworks/devel/sbs/36/scai.Bwitcpp.j265545/matlab/bin/glnxa64/libCppMicroServices.so.2.1.0)