diff --git a/CHANGELOG b/CHANGELOG index 6f13f3b408ab..c7d8efc55675 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ devel ----- +* Avoid the acquisition of a recursive read lock on server shutdown, which + could in theory lead to shutdown hangs at least if a concurrent thread is + trying to modify the list of collections (very unlikely and never observed + until now). + * Fixed display of unicode characters in Windows console. * Fixed issue BTS-531 "Error happens during EXE package installation if diff --git a/arangod/Replication/GlobalInitialSyncer.cpp b/arangod/Replication/GlobalInitialSyncer.cpp index 30327e858ecb..1f2ec602a103 100644 --- a/arangod/Replication/GlobalInitialSyncer.cpp +++ b/arangod/Replication/GlobalInitialSyncer.cpp @@ -305,8 +305,7 @@ Result GlobalInitialSyncer::updateServerInventory(VPackSlice const& leaderDataba if (!collection->system()) { // we will not drop system collections here toDrop.emplace_back(collection); } - }, - false); + }); for (auto const& collection : toDrop) { try { diff --git a/arangod/RestServer/DatabaseFeature.cpp b/arangod/RestServer/DatabaseFeature.cpp index 5cda9ce83c33..3d7b65b00318 100644 --- a/arangod/RestServer/DatabaseFeature.cpp +++ b/arangod/RestServer/DatabaseFeature.cpp @@ -484,14 +484,13 @@ void DatabaseFeature::stop() { #endif vocbase->stop(); - vocbase->processCollections( + vocbase->processCollectionsOnShutdown( [](LogicalCollection* collection) { // no one else must modify the collection's status while we are in // here collection->executeWhileStatusWriteLocked( [collection]() { collection->close(); }); - }, - true); + }); #ifdef ARANGODB_ENABLE_MAINTAINER_MODE // i am here for debugging only. diff --git a/arangod/VocBase/vocbase.cpp b/arangod/VocBase/vocbase.cpp index a1e7e08fcb36..05d68e0fd56c 100644 --- a/arangod/VocBase/vocbase.cpp +++ b/arangod/VocBase/vocbase.cpp @@ -1722,33 +1722,34 @@ std::vector> TRI_vocbase_t::views() { return views; } -void TRI_vocbase_t::processCollections(std::function const& cb, - bool includeDeleted) { +void TRI_vocbase_t::processCollectionsOnShutdown(std::function const& cb) { + RECURSIVE_WRITE_LOCKER(_dataSourceLock, _dataSourceLockWriteOwner); + + for (auto const& it : _collections) { + cb(it.get()); + } +} + +void TRI_vocbase_t::processCollections(std::function const& cb) { RECURSIVE_READ_LOCKER(_dataSourceLock, _dataSourceLockWriteOwner); - if (includeDeleted) { - for (auto const& it : _collections) { - cb(it.get()); - } - } else { - for (auto& entry : _dataSourceById) { - TRI_ASSERT(entry.second); + for (auto& entry : _dataSourceById) { + TRI_ASSERT(entry.second); - if (entry.second->category() != LogicalCollection::category()) { - continue; - } + if (entry.second->category() != LogicalCollection::category()) { + continue; + } #ifdef ARANGODB_ENABLE_MAINTAINER_MODE - auto collection = - std::dynamic_pointer_cast(entry.second); - TRI_ASSERT(collection); + auto collection = + std::dynamic_pointer_cast(entry.second); + TRI_ASSERT(collection); #else - auto collection = - std::static_pointer_cast(entry.second); + auto collection = + std::static_pointer_cast(entry.second); #endif - cb(collection.get()); - } + cb(collection.get()); } } diff --git a/arangod/VocBase/vocbase.h b/arangod/VocBase/vocbase.h index ebbca813a2a8..515d781d0b3f 100644 --- a/arangod/VocBase/vocbase.h +++ b/arangod/VocBase/vocbase.h @@ -286,8 +286,9 @@ struct TRI_vocbase_t { /// @brief returns all known collections std::vector> collections(bool includeDeleted); - void processCollections(std::function const& cb, - bool includeDeleted); + void processCollectionsOnShutdown(std::function const& cb); + + void processCollections(std::function const& cb); /// @brief returns names of all known collections std::vector collectionNames();