void RGWSyncTraceManager::finish_node(RGWSyncTraceNode *node)
{
- shunique_lock wl(lock, ceph::acquire_unique);
- if (!node) {
- return;
- }
- auto iter = nodes.find(node->handle);
- if (iter == nodes.end()) {
- /* not found, already finished */
- return;
- }
+ RGWSyncTraceNodeRef old_node;
- complete_nodes.push_back(iter->second);
- nodes.erase(iter);
+ {
+ shunique_lock wl(lock, ceph::acquire_unique);
+ if (!node) {
+ return;
+ }
+ auto iter = nodes.find(node->handle);
+ if (iter == nodes.end()) {
+ /* not found, already finished */
+ return;
+ }
+
+ if (complete_nodes.full()) {
+ /* take a reference to the entry that is going to be evicted,
+ * can't let it get evicted under lock held, otherwise
+ * it's a deadlock as it will call finish_node()
+ */
+ old_node = complete_nodes.front();
+ }
+
+ complete_nodes.push_back(iter->second);
+ nodes.erase(iter);
+ }
};
#endif