Re: [libgit2] Usage of declspec(thread) in include/git2/thread-utils.h
- Vicent Marti
- 2011-06-09 @ 11:27
this is a known issue that has been around our tracker for a while.
It's nice to see that you arrived to the same conclusion as Emeric and
I did when debugging it.
Currently, what we are doing on libgit2sharp (the .NET bindings for
libgit2) is building the library without threading support
(GIT_THREADS), which will completely disable all TLS declarations.
I'm working on a fix using the TlsValue methods from the Windows API
-- hopefully running libgit2 without threading will work as a
workaround for you until then.
On Thu, Jun 9, 2011 at 1:02 PM, Senthil Kumar
> I'm trying to use libgit2 on Windows as a static library linked into a
> C++/CLI DLL. I was able to build the DLL and load it in a managed (C#)
> application, but when trying to get a commit using git_commit_lookup, I'm
> getting an access violation error. This is not happening in all machines -
> on my Win7 x64 laptop, the code worked perfectly fine, but it consistently
> fails on my Win XP SP3 32 bit machine.
> I decided to debug and found that the access violation is occurring when
> g_last_error is accessed in the git__throw function (src\errors.c).
> Inspecting the g_last_error variable showed that it was pointing at a
> garbage address. When I went to the definition, I found that it was
> decorated with GIT_TLS, which in my Windows machine expands to
> declspec(thread). Removing the decoration and recompiling/relinking fixed
> the problem, but of course, the thread local nature of the last error
> variable is gone.
> As discussed in http://www.nynaeve.net/?p=180,
> http://blogs.msdn.com/b/oldnewthing/archive/2010/11/22/10094489.aspx and
> http://msdn.microsoft.com/en-us/library/ms682594.aspx, declspec(thread)
> apparently only works for DLLs that are linked directly to executables ("
> Specifically, implicit TLS does not operate when a module using it is not
> being loaded at process initialization time (during static import
> resolution)"). The CLR loads my C++/CLI DLL only when it needs to, and even
> then, it uses LoadLibrary, which means that there is no hope of
> declspec(thread) working correctly in this case.
> Windows Vista (and later) operating systems apparently handle
> declspec(thread) differently, so that's why it worked fine on my Win7
> To summarize, the current implementation cannot be used a static library
> linked to a C++/CLI (mixed mode) DLL, at least on pre-Windows Vista
> machines. The alternative is to use the explicit TlsGetValue/TlsSetValue