# HG changeset patch # User Sebastien Jodogne # Date 1447087182 -3600 # Node ID 70f544f9c38f4c7a603f3a53079ce87153d06f01 # Parent b268756c2cb9a26355e0063856414186277d19b6 fix possible deadlock in custom database plugins diff -r b268756c2cb9 -r 70f544f9c38f Plugins/Engine/OrthancPlugins.cpp --- a/Plugins/Engine/OrthancPlugins.cpp Mon Nov 09 09:34:18 2015 +0100 +++ b/Plugins/Engine/OrthancPlugins.cpp Mon Nov 09 17:39:42 2015 +0100 @@ -1287,7 +1287,32 @@ { VLOG(1) << "Calling service " << service << " from plugin " << plugin.GetPath(); - boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); + if (service == _OrthancPluginService_DatabaseAnswer) + { + // This case solves a deadlock at (*) reported by James Webster + // on 2015-10-27 that was present in versions of Orthanc <= + // 0.9.4 and related to database plugins implementing a custom + // index. The problem was that locking the database is already + // ensured by the "ServerIndex" class if the invoked service is + // "DatabaseAnswer". + + const _OrthancPluginDatabaseAnswer& p = + *reinterpret_cast(parameters); + + if (pimpl_->database_.get() != NULL) + { + pimpl_->database_->AnswerReceived(p); + return true; + } + else + { + LOG(ERROR) << "Cannot invoke this service without a custom database back-end"; + throw OrthancException(ErrorCode_BadRequest); + } + } + + + std::auto_ptr lock; // (*) switch (service) { @@ -1559,21 +1584,7 @@ } case _OrthancPluginService_DatabaseAnswer: - { - const _OrthancPluginDatabaseAnswer& p = - *reinterpret_cast(parameters); - - if (pimpl_->database_.get() != NULL) - { - pimpl_->database_->AnswerReceived(p); - return true; - } - else - { - LOG(ERROR) << "Cannot invoke this service without a custom database back-end"; - throw OrthancException(ErrorCode_BadRequest); - } - } + throw OrthancException(ErrorCode_InternalError); // Implemented before locking (*) case _OrthancPluginService_GetExpectedDatabaseVersion: {