diff --git a/core/base/src/TDirectory.cxx b/core/base/src/TDirectory.cxx
index b9aa5d9b91a0a637eb5dc3cb2202b735908a3547..393b1724163d8137c61ad6d9535daf0bb51b97bc 100644
--- a/core/base/src/TDirectory.cxx
+++ b/core/base/src/TDirectory.cxx
@@ -543,7 +543,10 @@ void TDirectory::Clear(Option_t *)
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Delete all objects from memory and directory structure itself.
-
+/// if option is "slow", iterate through the containers in a way to can handle
+///    'external' modification (induced by recursions)
+/// if option is "nodelete", write the TDirectory but do not delete the contained
+///    objects.
 void TDirectory::Close(Option_t *option)
 {
    if (!fList) {
@@ -553,26 +556,30 @@ void TDirectory::Close(Option_t *option)
    // Save the directory key list and header
    Save();
 
-   Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;
-   if (!slow) {
-      // Check if it is wise to use the fast deletion path.
-      TObjLink *lnk = fList->FirstLink();
-      while (lnk) {
-         if (lnk->GetObject()->IsA() == TDirectory::Class()) {
-            slow = kTRUE;
-            break;
+   Bool_t nodelete = option ? (!strcmp(option, "nodelete") ? kTRUE : kFALSE) : kFALSE;
+
+   if (!nodelete) {
+      Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;
+      if (!slow) {
+         // Check if it is wise to use the fast deletion path.
+         TObjLink *lnk = fList->FirstLink();
+         while (lnk) {
+            if (lnk->GetObject()->IsA() == TDirectory::Class()) {
+               slow = kTRUE;
+               break;
+            }
+            lnk = lnk->Next();
          }
-         lnk = lnk->Next();
       }
-   }
 
-   // Delete objects from directory list, this in turn, recursively closes all
-   // sub-directories (that were allocated on the heap)
-   // if this dir contains subdirs, we must use the slow option for Delete!
-   // we must avoid "slow" as much as possible, in particular Delete("slow")
-   // with a large number of objects (eg >10^5) would take for ever.
-   if (slow) fList->Delete("slow");
-   else      fList->Delete();
+      // Delete objects from directory list, this in turn, recursively closes all
+      // sub-directories (that were allocated on the heap)
+      // if this dir contains subdirs, we must use the slow option for Delete!
+      // we must avoid "slow" as much as possible, in particular Delete("slow")
+      // with a large number of objects (eg >10^5) would take for ever.
+      if (slow) fList->Delete("slow");
+      else      fList->Delete();
+   }
 
    CleanTargets();
 }
diff --git a/core/base/src/TROOT.cxx b/core/base/src/TROOT.cxx
index 34401511878c6114911fd65a20f6f832cbc6c0db..63578f63ad9448d555a3f2271dd57b1026e44993 100644
--- a/core/base/src/TROOT.cxx
+++ b/core/base/src/TROOT.cxx
@@ -1089,7 +1089,8 @@ namespace {
             // is not seen as part of the list.
             // We will later, remove all the object (see files->Clear()
             cursor->SetObject(&harmless); // this must not be zero otherwise things go wrong.
-            dir->Close();
+            // See related comment at the files->Clear("nodelete");
+            dir->Close("nodelete");
             // Put it back
             cursor->SetObject(dir);
          }
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index ae95138a9f9bc91f95a7658b4297bc45612a64b3..7b02c050f192d0dd761d28886041102aa0f6a411 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -2732,6 +2732,7 @@ Int_t TClass::GetBaseClassOffset(const TClass *toBase, void *address, bool isDer
    ClassInfo_t* derived = GetClassInfo();
    ClassInfo_t* base = toBase->GetClassInfo();
    if(derived && base) {
+      // TClingClassInfo::GetBaseOffset takes the lock.
       return gCling->ClassInfo_GetBaseOffset(derived, base, address, isDerivedObject);
    }
    else {
diff --git a/io/io/src/TDirectoryFile.cxx b/io/io/src/TDirectoryFile.cxx
index 627440ed38f0052416d26a48b06360f8bbf57915..7a7ecfc1a1c19fd4858e9554f1701e1597e204ea 100644
--- a/io/io/src/TDirectoryFile.cxx
+++ b/io/io/src/TDirectoryFile.cxx
@@ -532,7 +532,7 @@ TDirectory *TDirectoryFile::GetDirectory(const char *apath,
 ////////////////////////////////////////////////////////////////////////////////
 /// Delete all objects from memory and directory structure itself.
 
-void TDirectoryFile::Close(Option_t *)
+void TDirectoryFile::Close(Option_t *option)
 {
    if (!fList || !fSeekDir) {
       return;
@@ -541,20 +541,24 @@ void TDirectoryFile::Close(Option_t *)
    // Save the directory key list and header
    Save();
 
-   Bool_t fast = kTRUE;
-   TObjLink *lnk = fList->FirstLink();
-   while (lnk) {
-      if (lnk->GetObject()->IsA() == TDirectoryFile::Class()) {fast = kFALSE;break;}
-      lnk = lnk->Next();
-   }
-   // Delete objects from directory list, this in turn, recursively closes all
-   // sub-directories (that were allocated on the heap)
-   // if this dir contains subdirs, we must use the slow option for Delete!
-   // we must avoid "slow" as much as possible, in particular Delete("slow")
-   // with a large number of objects (eg >10^5) would take for ever.
-   {
-      if (fast) fList->Delete();
-      else      fList->Delete("slow");
+   Bool_t nodelete = option ? (!strcmp(option, "nodelete") ? kTRUE : kFALSE) : kFALSE;
+
+   if (!nodelete) {
+      Bool_t fast = kTRUE;
+      TObjLink *lnk = fList->FirstLink();
+      while (lnk) {
+         if (lnk->GetObject()->IsA() == TDirectoryFile::Class()) {fast = kFALSE;break;}
+         lnk = lnk->Next();
+      }
+      // Delete objects from directory list, this in turn, recursively closes all
+      // sub-directories (that were allocated on the heap)
+      // if this dir contains subdirs, we must use the slow option for Delete!
+      // we must avoid "slow" as much as possible, in particular Delete("slow")
+      // with a large number of objects (eg >10^5) would take for ever.
+      {
+         if (fast) fList->Delete();
+         else      fList->Delete("slow");
+      }
    }
 
    // Delete keys from key list (but don't delete the list header)
diff --git a/io/io/src/TFile.cxx b/io/io/src/TFile.cxx
index 01730b99f6cc1e0f771794f4fb86b72c791905b0..52089f63979b931b23845ed6328962507ad0b0d6 100644
--- a/io/io/src/TFile.cxx
+++ b/io/io/src/TFile.cxx
@@ -546,6 +546,17 @@ TFile::~TFile()
 {
    Close();
 
+   // In case where the TFile is still open at 'tear-down' time the order of operation will be
+   // call Close("nodelete")
+   // then later call delete TFile
+   // which means that at this point we might still have object held and those
+   // might requires a 'valid' TFile object in their desctructor (for example,
+   // TTree call's GetReadCache which expects a non-null fCacheReadMap).
+   // So delete the objects (if any) now.
+
+   if (fList)
+      fList->Delete("slow");
+
    SafeDelete(fAsyncHandle);
    SafeDelete(fCacheRead);
    SafeDelete(fCacheReadMap);