title: How to circumvent dlopen() caching?
body: <p>According to its <a href="http://man7.org/linux/man-pages/man3/dlopen.3.html" rel="nofollow noreferrer">man page</a>, <code>dlopen()</code> will not load the same library twice:</p>
  
  <blockquote>
    <p>If the <strong>same shared object</strong> is loaded again with dlopen(), the same
    object handle is returned.  The dynamic linker maintains reference
    counts for object handles, so a dynamically loaded shared object is
    not deallocated until dlclose() has been called on it as many times
    as dlopen() has succeeded on it.  Any initialization returns (see
    below) are called just once.  However, a subsequent dlopen() call
    that loads the same shared object with RTLD_NOW may force symbol
    resolution for a shared object earlier loaded with RTLD_LAZY.</p>
  </blockquote>
  
  <p>(emphasis mine).</p>
  
  <p>But what actually determines the identity of shared objects? I tried to look into the code, but did not come very far. Is it:</p>
  
  <ul>
  <li>some form of normalized path name (e.g. realpath?)</li>
  <li>the inode ?</li>
  <li>the contents of the libray?</li>
  </ul>
  
  <p>I am pretty sure that I can rule out this last point, since an actual filesystem copy yields two different handles.</p>
  
  <p>To explain the motivation behind this question: I am working with some code that has static global variables. I need multiple instances of that code to run in a thread-safe manner. My current approach is to compile and link said code into a dynamic library and load that library multiple times. With some linker magic, it appears to create several copies of the globals and resolve access in each library to its own copies. The only problem is that my prototype copies the generated library n times for n concurrent uses. This is not only somewhat ugly but I also suspect that it might break on a different platform.</p>
  
  <p>So what is the exact behaviour of <code>dlopen()</code> according to the POSIX standard?</p>
  
  <p><strong>edit:</strong> Because it came up in a comment and an answer, no refactoring the code is definitely not an option. It would involve months or even years of work and potentially sacrifice all benefits of using the code in the first place. There <strong>exists</strong> an ongoing research project that might solve this problem in a much cleaner way, but it is actual research and might fail. I need a solution now.</p>
  
  <p><strong>edit2:</strong> Because people still seem to not believe the usecase is actually valid. I am working on a pure functional language, that shall be embedded into a larger C/C++ application. Because I need a prototype with a garbage collector, a proven typechecker, and reasonable performance ASAP, I used OCaml as intermediate code. Right now, I am compiling a source module into an OCaml module, link the generated object code (including startup etc.) into a shared library <strong>with the OCaml runtime</strong> and dlopen() <strong>that</strong> shared library. Every .so has its own copy of the runtime, including several global variabels (e.g. the pointer to the young generation) and that is, or rather should be, totally fine. The library exposes exactly two functions: An initializer and a single export that does whatever the original module is intended to do. No symbols of the OCaml runtime are exported/shared. when I load the library, its internal symbols are relocated as expected, the only issue I have right now is that I actually need to copy the .so file for each instance of the job at runtime.</p>
  
  <p>Regarding thread-local-storage: That is actually an interesting idea, as the modification to the runtime is indeed rather simple. But the problem is the machine code generated by the OCaml compiler, as it cannot emit loading instructions for tls symbols (yet?). </p>