From 26fd26e73b07624207556e4725e1f7f51be5aa3a Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Mon, 17 Jun 2013 15:47:30 -0500
Subject: [PATCH] Fix ROOT-5287, by calling InitializeGraphics in TCanvas::Init

gApplication->InitializeGraphics must be called after loading the Gpad library
(but *not* during the loading itself, as it need the dictionary to be fully
loaded).  Previously it was called from gSystem->Load.  Before this commit, it
was not called when the library is loaded in reaction to a missing symbol, i.e.
at 'JIT link time', by NotifyLazyFunctionCreators which calls TCling's
autoloadCallback which does *not* call InitializeGraphics.

Adding InitializeGraphics to TCling's autoloadCallback is not a viable solution
since it is being called during the 'link-phase' of the code generation (aka at
the end of llvm::JIT::getPointerToFunction) and because the JIT is not
re-entrant (it has an explicit assert against it: "Error: Recursive compilation
detected!") *and* because InitializeGraphics must load the plugin scripts ...
which means compiling.

So instead we delay the call to InitializeGraphics until TCanvas::init (and if
find other places that needs it, we will put it there too).
---
 core/base/src/TSystem.cxx   | 13 -------------
 core/meta/src/TCling.cxx    |  1 +
 graf2d/gpad/src/TCanvas.cxx |  6 ++++++
 3 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/core/base/src/TSystem.cxx b/core/base/src/TSystem.cxx
index 1104e430225..bad725ff977 100644
--- a/core/base/src/TSystem.cxx
+++ b/core/base/src/TSystem.cxx
@@ -1765,7 +1765,6 @@ int TSystem::Load(const char *module, const char *entry, Bool_t system)
    AbstractMethod("Load");
    return 0;
 #else
-   static int recCall = 0;
 
    // don't load libraries that have already been loaded
    TString libs( GetLibraries() );
@@ -1814,8 +1813,6 @@ int TSystem::Load(const char *module, const char *entry, Bool_t system)
       }
    }
 
-   recCall++;
-
    char *path = DynamicPathName(module);
 
    int ret = -1;
@@ -1848,7 +1845,6 @@ int TSystem::Load(const char *module, const char *entry, Bool_t system)
                     deplib, ((TObjString*)tokens->At(0))->GetName());
             if ((ret = Load(deplib, "", system)) < 0) {
                delete tokens;
-               recCall--;
                return ret;
             }
          }
@@ -1896,15 +1892,6 @@ int TSystem::Load(const char *module, const char *entry, Bool_t system)
       delete [] path;
    }
 
-   recCall--;
-
-   // will load and initialize graphics libraries if
-   // TApplication::NeedGraphicsLibs() has been called by a
-   // library static initializer, only do this when Load() is
-   // not called recursively
-   if (recCall == 0 && gApplication)
-      gApplication->InitializeGraphics();
-
    if (!entry || !entry[0] || ret < 0) return ret;
 
    Func_t f = DynFindSymbol(module, entry);
diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index db474d311f4..978a008f70c 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -568,6 +568,7 @@ void* autoloadCallback(const std::string& mangled_name)
          return 0;
       }
    }
+
    //fprintf(stderr, "load succeeded.\n");
    // Get the address of the function being called.
    void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
diff --git a/graf2d/gpad/src/TCanvas.cxx b/graf2d/gpad/src/TCanvas.cxx
index f7a03d71dc1..f3a8c7f848c 100644
--- a/graf2d/gpad/src/TCanvas.cxx
+++ b/graf2d/gpad/src/TCanvas.cxx
@@ -492,6 +492,12 @@ void TCanvas::Init()
    if (!gApplication)
       TApplication::CreateApplication();
 
+   // Load and initialize graphics libraries if
+   // TApplication::NeedGraphicsLibs() has been called by a
+   // library static initializer.
+   if (gApplication)
+      gApplication->InitializeGraphics();
+
    // Get some default from .rootrc. Used in fCanvasImp->InitWindow().
    fHighLightColor     = gEnv->GetValue("Canvas.HighLightColor", kRed);
    SetBit(kMoveOpaque,   gEnv->GetValue("Canvas.MoveOpaque", 0));
-- 
GitLab