Mercurial > hg > orthanc-databases
changeset 802:f31f174d194b
fix the lifetime of the backend
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Fri, 10 Apr 2026 19:21:43 +0200 |
| parents | f9e4d92b0e97 |
| children | accca9ae6111 |
| files | Framework/Plugins/DatabaseBackendAdapterV4.cpp |
| diffstat | 1 files changed, 37 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/Framework/Plugins/DatabaseBackendAdapterV4.cpp Fri Apr 10 18:42:44 2026 +0200 +++ b/Framework/Plugins/DatabaseBackendAdapterV4.cpp Fri Apr 10 19:21:43 2026 +0200 @@ -48,7 +48,9 @@ namespace OrthancDatabases { static bool isBackendInUse_ = false; // Only for sanity checks - static BaseIndexConnectionsPool* connectionPool_ = NULL; // Only for the AuditLogHandler + + // The AuditLogHandler necessitates the plugin to manage the resources associated with the pool of connections + static std::unique_ptr<BaseIndexConnectionsPool> connectionPool_; static Orthanc::DatabasePluginMessages::ResourceType Convert(OrthancPluginResourceType resourceType) { @@ -1454,6 +1456,20 @@ const void* requestData, uint64_t requestSize) { + if (rawPool == NULL || + connectionPool_.get() == NULL || + rawPool != connectionPool_.get()) + { + LOG(ERROR) << "Internal error: Incorrect state for the pool of connections"; + return OrthancPluginErrorCode_InternalError; + } + + if (!isBackendInUse_) + { + LOG(ERROR) << "More than one index backend was registered, internal error"; + return OrthancPluginErrorCode_InternalError; + } + Orthanc::DatabasePluginMessages::Request request; if (!request.ParseFromArray(requestData, requestSize)) { @@ -1461,22 +1477,14 @@ return OrthancPluginErrorCode_InternalError; } - if (rawPool == NULL) - { - LOG(ERROR) << "Received a NULL pointer from the database"; - return OrthancPluginErrorCode_InternalError; - } - try { - BaseIndexConnectionsPool& pool = *reinterpret_cast<BaseIndexConnectionsPool*>(rawPool); - Orthanc::DatabasePluginMessages::Response response; switch (request.type()) { case Orthanc::DatabasePluginMessages::REQUEST_DATABASE: - ProcessDatabaseOperation(*response.mutable_database_response(), request.database_request(), pool); + ProcessDatabaseOperation(*response.mutable_database_response(), request.database_request(), *connectionPool_); break; case Orthanc::DatabasePluginMessages::REQUEST_TRANSACTION: @@ -1498,7 +1506,7 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Cannot serialize to protobuf"); } - if (OrthancPluginCreateMemoryBuffer64(pool.GetContext(), serializedResponse, s.size()) != OrthancPluginErrorCode_Success) + if (OrthancPluginCreateMemoryBuffer64(connectionPool_->GetContext(), serializedResponse, s.size()) != OrthancPluginErrorCode_Success) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory, "Cannot allocate a memory buffer"); } @@ -1537,26 +1545,23 @@ static void FinalizeBackend(void* rawPool) { - if (rawPool != NULL) + if (rawPool == NULL || + connectionPool_.get() == NULL || + connectionPool_.get() != rawPool) { - BaseIndexConnectionsPool* pool = reinterpret_cast<BaseIndexConnectionsPool*>(rawPool); - - if (isBackendInUse_) - { - isBackendInUse_ = false; - connectionPool_ = NULL; - } - else - { - LOG(ERROR) << "More than one index backend was registered, internal error"; - } + LOG(ERROR) << "Internal error: Incorrect state for the pool of connections"; + } - delete pool; + if (isBackendInUse_) + { + isBackendInUse_ = false; } else { - LOG(ERROR) << "Received a null pointer from the Orthanc core, internal error"; + LOG(ERROR) << "More than one index backend was registered, internal error"; } + + connectionPool_.reset(NULL); } @@ -1569,7 +1574,7 @@ uint32_t logDataSize) { if (!isBackendInUse_ || - connectionPool_ == NULL) + connectionPool_.get() == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } @@ -1785,29 +1790,28 @@ unsigned int maxDatabaseRetries, unsigned int housekeepingDelaySeconds) { - std::unique_ptr<BaseIndexConnectionsPool> pool; - + // The "connectionPool_" takes the ownership of the backend if (useDynamicConnectionPool) { - pool.reset(new DynamicIndexConnectionsPool(backend, countConnections, housekeepingDelaySeconds)); + connectionPool_.reset(new DynamicIndexConnectionsPool(backend, countConnections, housekeepingDelaySeconds)); } else { - pool.reset(new IndexConnectionsPool(backend, countConnections, housekeepingDelaySeconds)); + connectionPool_.reset(new IndexConnectionsPool(backend, countConnections, housekeepingDelaySeconds)); } if (isBackendInUse_) { + connectionPool_.reset(); // This implies "delete backend" throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } OrthancPluginContext* context = backend->GetContext(); - connectionPool_ = pool.get(); // we need to keep a pointer on the connectionPool for the static Audit log handler - if (OrthancPluginRegisterDatabaseBackendV4(context, pool.release(), maxDatabaseRetries, + if (OrthancPluginRegisterDatabaseBackendV4(context, connectionPool_.get(), maxDatabaseRetries, CallBackend, FinalizeBackend) != OrthancPluginErrorCode_Success) { - delete backend; + connectionPool_.reset(); // This implies "delete backend" throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Unable to register the database backend"); }
