aboutsummaryrefslogtreecommitdiffstats
path: root/src/init.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2010-07-21 08:00:09 +0000
committerWerner Koch <[email protected]>2010-07-21 08:00:09 +0000
commit2444ddfc2c9043279341b80c5ce1c7175247cf1a (patch)
treec2e344074bf650c4054e0b2d5ebac0d01f10579a /src/init.c
parentUpdate (diff)
downloadlibgpg-error-2444ddfc2c9043279341b80c5ce1c7175247cf1a.tar.gz
libgpg-error-2444ddfc2c9043279341b80c5ce1c7175247cf1a.zip
Add gpg_err_deinitlibgpg-error-1.9
Prepare a new release.
Diffstat (limited to 'src/init.c')
-rw-r--r--src/init.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/src/init.c b/src/init.c
index 63c20de..d30435a 100644
--- a/src/init.c
+++ b/src/init.c
@@ -40,7 +40,9 @@
#if HAVE_W32_SYSTEM
-static int tls_index; /* Index for the TLS functions. */
+#include <windows.h>
+
+static int tls_index = TLS_OUT_OF_INDEXES; /* Index for the TLS functions. */
static char *get_locale_dir (void);
static void drop_locale_dir (char *locale_dir);
@@ -74,12 +76,29 @@ gpg_error_t
gpg_err_init (void)
{
#ifdef HAVE_W32_SYSTEM
+# ifdef DLL_EXPORT
/* We always have a constructor and thus this function is called
automatically. Due to the way the C init code of mingw works,
the constructors are called before our DllMain function is
called. The problem with that is that the TLS has not been setup
and w32-gettext.c requires TLS. To solve this we do nothing here
but call the actual init code from our DllMain. */
+# else /*!DLL_EXPORT*/
+ /* Note that if the TLS is actually used, we can't release the TLS
+ as there is no way to know when a thread terminates (i.e. no
+ thread-specific-atexit). You are really better off to use the
+ DLL! */
+ if (tls_index == TLS_OUT_OF_INDEXES)
+ {
+ tls_index = TlsAlloc ();
+ if (tls_index == TLS_OUT_OF_INDEXES)
+ {
+ /* No way to continue - commit suicide. */
+ abort ();
+ }
+ real_init ();
+ }
+# endif /*!DLL_EXPORT*/
#else
real_init ();
#endif
@@ -87,11 +106,41 @@ gpg_err_init (void)
}
+/* Deinitialize libgpg-error. This function is only used in special
+ circumstances. No gpg-error function should be used after this
+ function has been called. A value of 0 passed for MODE
+ deinitializes the entire libgpg-error, a value of 1 releases
+ resources allocated for the current thread and only that thread may
+ not anymore access libgpg-error after such a call. Under Windows
+ this function may be called from the DllMain function of a DLL
+ which statically links to libgpg-error. */
+void
+gpg_err_deinit (int mode)
+{
+#if defined (HAVE_W32_SYSTEM) && !defined(DLL_EXPORT)
+ struct tls_space_s *tls;
+
+ tls = TlsGetValue (tls_index);
+ if (tls)
+ {
+ TlsSetValue (tls_index, NULL);
+ LocalFree (tls);
+ }
+
+ if (mode == 0)
+ {
+ TlsFree (tls_index);
+ tls_index = TLS_OUT_OF_INDEXES;
+ }
+#else
+ (void)mode;
+#endif
+}
+
+
#ifdef HAVE_W32_SYSTEM
-#include <windows.h>
-
/* Return a malloced string encoded in UTF-8 from the wide char input
string STRING. Caller must free this value. Returns NULL on
failure. Caller may use GetLastError to get the actual error
@@ -292,6 +341,7 @@ gpg_err_set_errno (int err)
/* Entry point called by the DLL loader. */
+#ifdef DLL_EXPORT
int WINAPI
DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
{
@@ -336,7 +386,7 @@ DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
return TRUE;
}
-
+#endif /*DLL_EXPORT*/
#else /*!HAVE_W32_SYSTEM*/