Allow multiple wimlib_global_init/cleanup per app
authorEric Biggers <ebiggers3@gmail.com>
Fri, 20 Jun 2014 00:32:36 +0000 (19:32 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Fri, 20 Jun 2014 00:32:36 +0000 (19:32 -0500)
include/wimlib/encoding.h
src/encoding.c
src/wim.c

index 00f1a38..b48fe9c 100644 (file)
@@ -7,6 +7,9 @@
 
 #include <string.h>
 
+extern void
+iconv_global_init(void);
+
 extern void
 iconv_global_cleanup(void);
 
index 8edf228..ff90a23 100644 (file)
@@ -68,8 +68,6 @@ struct iconv_node {
 struct iconv_list_head name = {                                \
        .from_encoding = from,                          \
        .to_encoding = to,                              \
-       .list = LIST_HEAD_INIT(name.list),              \
-       .mutex = PTHREAD_MUTEX_INITIALIZER,             \
 }
 
 static iconv_t *
@@ -363,6 +361,13 @@ utf8_to_tstr_simple(const char *utf8str, tchar **out)
        return utf8_to_tstr(utf8str, strlen(utf8str), out, &out_nbytes);
 }
 
+static void
+iconv_init(struct iconv_list_head *head)
+{
+       pthread_mutex_init(&head->mutex, NULL);
+       INIT_LIST_HEAD(&head->list);
+}
+
 static void
 iconv_cleanup(struct iconv_list_head *head)
 {
@@ -377,6 +382,19 @@ iconv_cleanup(struct iconv_list_head *head)
        }
 }
 
+void
+iconv_global_init(void)
+{
+       iconv_init(&iconv_utf8_to_tstr);
+       iconv_init(&iconv_tstr_to_utf8);
+#if !TCHAR_IS_UTF16LE
+       iconv_init(&iconv_utf16le_to_tstr);
+       iconv_init(&iconv_tstr_to_utf16le);
+       iconv_init(&iconv_utf16le_to_utf8);
+       iconv_init(&iconv_utf8_to_utf16le);
+#endif
+}
+
 void
 iconv_global_cleanup(void)
 {
index cf7965e..a3dd135 100644 (file)
--- a/src/wim.c
+++ b/src/wim.c
@@ -1011,13 +1011,13 @@ wimlib_get_version(void)
        return WIMLIB_VERSION_CODE;
 }
 
+static bool lib_initialized = false;
+
 /* API function documented in wimlib.h  */
 WIMLIBAPI int
 wimlib_global_init(int init_flags)
 {
-       static bool already_inited = false;
-
-       if (already_inited)
+       if (lib_initialized)
                return 0;
 
        if (init_flags & ~(WIMLIB_INIT_FLAG_ASSUME_UTF8 |
@@ -1043,12 +1043,13 @@ wimlib_global_init(int init_flags)
                        return ret;
        }
 #endif
+       iconv_global_init();
        init_upcase();
        if (init_flags & WIMLIB_INIT_FLAG_DEFAULT_CASE_SENSITIVE)
                default_ignore_case = false;
        else if (init_flags & WIMLIB_INIT_FLAG_DEFAULT_CASE_INSENSITIVE)
                default_ignore_case = true;
-       already_inited = true;
+       lib_initialized = true;
        return 0;
 }
 
@@ -1056,6 +1057,8 @@ wimlib_global_init(int init_flags)
 WIMLIBAPI void
 wimlib_global_cleanup(void)
 {
+       if (!lib_initialized)
+               return;
        libxml_global_cleanup();
        iconv_global_cleanup();
 #ifdef __WIN32__
@@ -1063,4 +1066,5 @@ wimlib_global_cleanup(void)
 #endif
        cleanup_decompressor_params();
        cleanup_compressor_params();
+       lib_initialized = false;
 }