[gmime: 3/4] Removed caching of iconv descriptors; not really needed anymore



commit ad5366ddc4d9fdc833db6388e41aa6cae67485b2
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date:   Tue Mar 21 16:59:11 2017 -0400

    Removed caching of iconv descriptors; not really needed anymore

 gmime/gmime-header.c      |    2 -
 gmime/gmime-iconv-utils.c |  128 ++++++++------------
 gmime/gmime-iconv.c       |  293 +--------------------------------------------
 gmime/gmime-iconv.h       |    6 +-
 gmime/gmime.c             |    9 +--
 tests/test-iconv.c        |   83 +-------------
 util/Makefile.am          |    4 -
 util/cache.c              |  128 --------------------
 util/cache.h              |   68 -----------
 util/list.c               |  118 ------------------
 util/list.h               |   59 ---------
 11 files changed, 57 insertions(+), 841 deletions(-)
---
diff --git a/gmime/gmime-header.c b/gmime/gmime-header.c
index 9a36ce1..3e0b347 100644
--- a/gmime/gmime-header.c
+++ b/gmime/gmime-header.c
@@ -34,8 +34,6 @@
 #include "gmime-events.h"
 #include "gmime-utils.h"
 
-#include "list.h"
-
 
 /**
  * SECTION: gmime-header
diff --git a/gmime/gmime-iconv-utils.c b/gmime/gmime-iconv-utils.c
index a288982..aa5ca2b 100644
--- a/gmime/gmime-iconv-utils.c
+++ b/gmime/gmime-iconv-utils.c
@@ -47,74 +47,6 @@
  **/
 
 
-#ifdef G_THREADS_ENABLED
-static GMutex lock;
-#define UNLOCK() g_mutex_unlock (&lock)
-#define LOCK()   g_mutex_lock (&lock);
-#else
-#define UNLOCK()
-#define LOCK()
-#endif /* G_THREADS_ENABLED */
-
-static iconv_t utf8_to_locale = (iconv_t) -1;
-static iconv_t locale_to_utf8 = (iconv_t) -1;
-static int initialized = 0;
-
-
-void
-g_mime_iconv_utils_init (void)
-{
-       const char *utf8, *locale;
-       
-       initialized = MAX (initialized, 0);
-       
-       if (initialized++)
-               return;
-       
-#ifdef G_THREADS_ENABLED
-       g_mutex_init (&lock);
-#endif
-       
-       utf8 = g_mime_charset_iconv_name ("UTF-8");
-       
-       if (!(locale = g_mime_locale_charset ()))
-               locale = "US-ASCII";
-       
-       if ((locale = g_mime_charset_iconv_name (locale))) {
-               utf8_to_locale = iconv_open (locale, utf8);
-               locale_to_utf8 = iconv_open (utf8, locale);
-       }
-}
-
-void
-g_mime_iconv_utils_shutdown (void)
-{
-       if (--initialized)
-               return;
-       
-#ifdef G_THREADS_ENABLED
-       if (glib_check_version (2, 37, 4) == NULL) {
-               /* The implementation of g_mutex_clear() prior
-                * to glib 2.37.4 did not properly reset the
-                * internal mutex pointer to NULL, so re-initializing
-                * GMime would not properly re-initialize the mutexes.
-                **/
-               g_mutex_clear (&lock);
-       }
-#endif
-       
-       if (utf8_to_locale != (iconv_t) -1) {
-               iconv_close (utf8_to_locale);
-               utf8_to_locale = (iconv_t) -1;
-       }
-       
-       if (locale_to_utf8 != (iconv_t) -1) {
-               iconv_close (locale_to_utf8);
-               locale_to_utf8 = (iconv_t) -1;
-       }
-}
-
-
 /**
  * g_mime_iconv_strndup: (skip)
  * @cd: conversion descriptor
@@ -247,11 +179,19 @@ g_mime_iconv_strdup (iconv_t cd, const char *str)
 char *
 g_mime_iconv_locale_to_utf8 (const char *str)
 {
+       const char *locale, *utf8;
+       iconv_t cd;
        char *buf;
        
-       LOCK ();
-       buf = g_mime_iconv_strdup (locale_to_utf8, str);
-       UNLOCK ();
+       if (!(locale = g_mime_locale_charset ()))
+               locale = "iso-8859-1";
+       
+       locale = g_mime_charset_iconv_name (locale);
+       utf8 = g_mime_charset_iconv_name ("UTF-8");
+       
+       cd = iconv_open (locale, utf8);
+       buf = g_mime_iconv_strdup (cd, str);
+       iconv_close (cd);
        
        return buf;
 }
@@ -271,11 +211,19 @@ g_mime_iconv_locale_to_utf8 (const char *str)
 char *
 g_mime_iconv_locale_to_utf8_length (const char *str, size_t n)
 {
+       const char *locale, *utf8;
+       iconv_t cd;
        char *buf;
        
-       LOCK ();
-       buf = g_mime_iconv_strndup (locale_to_utf8, str, n);
-       UNLOCK ();
+       if (!(locale = g_mime_locale_charset ()))
+               locale = "iso-8859-1";
+       
+       locale = g_mime_charset_iconv_name (locale);
+       utf8 = g_mime_charset_iconv_name ("UTF-8");
+       
+       cd = iconv_open (locale, utf8);
+       buf = g_mime_iconv_strndup (cd, str, n);
+       iconv_close (cd);
        
        return buf;
 }
@@ -294,11 +242,21 @@ g_mime_iconv_locale_to_utf8_length (const char *str, size_t n)
 char *
 g_mime_iconv_utf8_to_locale (const char *str)
 {
+       const char *locale, *utf8;
+       iconv_t cd;
        char *buf;
        
-       LOCK ();
-       buf = g_mime_iconv_strdup (utf8_to_locale, str);
-       UNLOCK ();
+       if (!(locale = g_mime_locale_charset ()))
+               return g_strdup (str);
+       
+       locale = g_mime_charset_iconv_name (locale);
+       utf8 = g_mime_charset_iconv_name ("UTF-8");
+       
+       if ((cd = iconv_open (utf8, locale)) == (iconv_t) -1)
+               return g_strdup (str);
+       
+       buf = g_mime_iconv_strdup (cd, str);
+       iconv_close (cd);
        
        return buf;
 }
@@ -318,11 +276,21 @@ g_mime_iconv_utf8_to_locale (const char *str)
 char *
 g_mime_iconv_utf8_to_locale_length (const char *str, size_t n)
 {
+       const char *locale, *utf8;
+       iconv_t cd;
        char *buf;
        
-       LOCK ();
-       buf = g_mime_iconv_strndup (utf8_to_locale, str, n);
-       UNLOCK ();
+       if (!(locale = g_mime_locale_charset ()))
+               return g_strndup (str, n);
+       
+       locale = g_mime_charset_iconv_name (locale);
+       utf8 = g_mime_charset_iconv_name ("UTF-8");
+       
+       if ((cd = iconv_open (utf8, locale)) == (iconv_t) -1)
+               return g_strndup (str, n);
+       
+       buf = g_mime_iconv_strndup (cd, str, n);
+       iconv_close (cd);
        
        return buf;
 }
diff --git a/gmime/gmime-iconv.c b/gmime/gmime-iconv.c
index d7795f7..158c8b6 100644
--- a/gmime/gmime-iconv.c
+++ b/gmime/gmime-iconv.c
@@ -25,18 +25,9 @@
 
 #include <glib.h>
 #include <errno.h>
-#include <string.h>
-#include <stdio.h>
 
 #include "gmime-charset.h"
 #include "gmime-iconv.h"
-#include "cache.h"
-
-#ifdef ENABLE_WARNINGS
-#define w(x) x
-#else
-#define w(x)
-#endif /* ENABLE_WARNINGS */
 
 
 /**
@@ -45,197 +36,11 @@
  * @short_description: Low-level routines for converting text from one charset to another
  * @see_also:
  *
- * These functions are wrappers around the system iconv(3)
- * routines. The purpose of these wrappers are two-fold:
- *
- * 1. Cache iconv_t descriptors for you in order to optimize
- * opening/closing many descriptors frequently
- *
- * and
- *
- * 2. To use the appropriate system charset alias for the MIME charset
- * names given as arguments.
+ * These functions are wrappers around the system iconv(3) routines. The
+ * purpose of this wrapper is to use the appropriate system charset alias for
+ * the MIME charset names given as arguments.
  **/
 
-#define ICONV_CACHE_SIZE   (16)
-
-typedef struct {
-       CacheNode node;
-       guint32 refcount : 31;
-       guint32 used : 1;
-       iconv_t cd;
-} IconvCacheNode;
-
-
-static Cache *iconv_cache = NULL;
-static GHashTable *iconv_open_hash = NULL;
-static int initialized = 0;
-
-#ifdef GMIME_ICONV_DEBUG
-static int cache_misses = 0;
-static int shutdown = 0;
-#define d(x) x
-#else
-#define d(x)
-#endif /* GMIME_ICONV_DEBUG */
-
-#ifdef G_THREADS_ENABLED
-static GMutex lock;
-#define ICONV_CACHE_UNLOCK() g_mutex_unlock (&lock);
-#define ICONV_CACHE_LOCK()   g_mutex_lock (&lock);
-#else
-#define ICONV_CACHE_UNLOCK()
-#define ICONV_CACHE_LOCK()
-#endif /* G_THREADS_ENABLED */
-
-
-/* caller *must* hold the iconv_cache_lock to call any of the following functions */
-
-
-/**
- * iconv_cache_node_new: (skip)
- * @key: cache key
- * @cd: iconv descriptor
- *
- * Creates a new cache node, inserts it into the cache and increments
- * the cache size.
- *
- * Returns: a pointer to the newly allocated cache node.
- **/
-static IconvCacheNode *
-iconv_cache_node_new (const char *key, iconv_t cd)
-{
-       IconvCacheNode *node;
-       
-#ifdef GMIME_ICONV_DEBUG
-       cache_misses++;
-#endif
-       
-       node = (IconvCacheNode *) cache_node_insert (iconv_cache, key);
-       node->refcount = 1;
-       node->used = TRUE;
-       node->cd = cd;
-       
-       return node;
-}
-
-
-static void
-iconv_cache_node_free (CacheNode *node)
-{
-       IconvCacheNode *inode = (IconvCacheNode *) node;
-       
-#ifdef GMIME_ICONV_DEBUG
-       if (shutdown) {
-               fprintf (stderr, "%s: open=%d; used=%s\n", node->key,
-                        inode->refcount, inode->used ? "yes" : "no");
-       }
-#endif
-       
-       iconv_close (inode->cd);
-}
-
-
-/**
- * iconv_cache_node_expire:
- * @node: cache node
- *
- * Decides whether or not a cache node should be expired.
- **/
-static gboolean
-iconv_cache_node_expire (Cache *cache, CacheNode *node)
-{
-       IconvCacheNode *inode = (IconvCacheNode *) node;
-       
-       if (inode->refcount == 0)
-               return TRUE;
-       
-       return FALSE;
-}
-
-
-static void
-iconv_open_node_free (gpointer key, gpointer value, gpointer user_data)
-{
-       iconv_t cd = (iconv_t) key;
-       IconvCacheNode *node;
-       
-       node = (IconvCacheNode *) cache_node_lookup (iconv_cache, value, FALSE);
-       g_assert (node);
-       
-       if (cd != node->cd) {
-               node->refcount--;
-               iconv_close (cd);
-       }
-}
-
-
-/**
- * g_mime_iconv_shutdown:
- *
- * Frees internal iconv caches created in g_mime_iconv_init().
- *
- * Note: this function is called for you by g_mime_shutdown().
- **/
-void
-g_mime_iconv_shutdown (void)
-{
-       if (--initialized)
-               return;
-       
-#ifdef GMIME_ICONV_DEBUG
-       fprintf (stderr, "There were %d iconv cache misses\n", cache_misses);
-       fprintf (stderr, "The following %d iconv cache buckets are still open:\n", iconv_cache->size);
-       shutdown = 1;
-#endif
-       
-#ifdef G_THREADS_ENABLED
-       if (glib_check_version (2, 37, 4) == NULL) {
-               /* The implementation of g_mutex_clear() prior
-                * to glib 2.37.4 did not properly reset the
-                * internal mutex pointer to NULL, so re-initializing
-                * GMime would not properly re-initialize the mutexes.
-                **/
-               g_mutex_clear (&lock);
-       }
-#endif
-       
-       g_hash_table_foreach (iconv_open_hash, iconv_open_node_free, NULL);
-       g_hash_table_destroy (iconv_open_hash);
-       iconv_open_hash = NULL;
-       
-       cache_free (iconv_cache);
-       iconv_cache = NULL;
-}
-
-
-/**
- * g_mime_iconv_init:
- *
- * Initialize GMime's iconv cache. This *MUST* be called before any
- * gmime-iconv interfaces will work correctly.
- *
- * Note: this function is called for you by g_mime_init().
- **/
-void
-g_mime_iconv_init (void)
-{
-       initialized = MAX (initialized, 0);
-       
-       if (initialized++)
-               return;
-       
-#ifdef G_THREADS_ENABLED
-       g_mutex_init (&lock);
-#endif
-       
-       g_mime_charset_map_init ();
-       
-       iconv_open_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
-       iconv_cache = cache_new (iconv_cache_node_expire, iconv_cache_node_free,
-                                sizeof (IconvCacheNode), ICONV_CACHE_SIZE);
-}
-
 
 /**
  * g_mime_iconv_open: (skip)
@@ -256,10 +61,6 @@ g_mime_iconv_init (void)
 iconv_t
 g_mime_iconv_open (const char *to, const char *from)
 {
-       IconvCacheNode *node;
-       iconv_t cd;
-       char *key;
-       
        if (from == NULL || to == NULL) {
                errno = EINVAL;
                return (iconv_t) -1;
@@ -270,57 +71,8 @@ g_mime_iconv_open (const char *to, const char *from)
        
        from = g_mime_charset_iconv_name (from);
        to = g_mime_charset_iconv_name (to);
-       key = g_alloca (strlen (from) + strlen (to) + 2);
-       sprintf (key, "%s:%s", from, to);
-       
-       ICONV_CACHE_LOCK ();
-       
-       if ((node = (IconvCacheNode *) cache_node_lookup (iconv_cache, key, TRUE))) {
-               if (node->used) {
-                       if ((cd = iconv_open (to, from)) == (iconv_t) -1)
-                               goto exception;
-               } else {
-                       /* Apparently iconv on Solaris <= 7 segfaults if you pass in
-                        * NULL for anything but inbuf; work around that. (NULL outbuf
-                        * or NULL *outbuf is allowed by Unix98.)
-                        */
-                       size_t inleft = 0, outleft = 0;
-                       char *outbuf = NULL;
-                       
-                       cd = node->cd;
-                       node->used = TRUE;
-                       
-                       /* reset the descriptor */
-                       iconv (cd, NULL, &inleft, &outbuf, &outleft);
-               }
-               
-               node->refcount++;
-       } else {
-               if ((cd = iconv_open (to, from)) == (iconv_t) -1)
-                       goto exception;
-               
-               node = iconv_cache_node_new (key, cd);
-       }
-       
-       g_hash_table_insert (iconv_open_hash, cd, ((CacheNode *) node)->key);
-       
-       ICONV_CACHE_UNLOCK ();
        
-       return cd;
-       
- exception:
-       
-       ICONV_CACHE_UNLOCK ();
-       
-#if w(!)0
-       if (errno == EINVAL)
-               g_warning ("Conversion from '%s' to '%s' is not supported", from, to);
-       else
-               g_warning ("Could not open converter from '%s' to '%s': %s",
-                          from, to, strerror (errno));
-#endif
-       
-       return cd;
+       return iconv_open (to, from);
 }
 
 
@@ -338,40 +90,5 @@ g_mime_iconv_open (const char *to, const char *from)
 int
 g_mime_iconv_close (iconv_t cd)
 {
-       IconvCacheNode *node;
-       const char *key;
-       
-       if (cd == (iconv_t) -1)
-               return 0;
-       
-       ICONV_CACHE_LOCK ();
-       
-       if ((key = g_hash_table_lookup (iconv_open_hash, cd))) {
-               g_hash_table_remove (iconv_open_hash, cd);
-               
-               node = (IconvCacheNode *) cache_node_lookup (iconv_cache, key, FALSE);
-               g_assert (node);
-               
-               if (iconv_cache->size > ICONV_CACHE_SIZE) {
-                       /* expire before unreffing this node so that it wont get uncached */
-                       cache_expire_unused (iconv_cache);
-               }
-               
-               node->refcount--;
-               
-               if (cd == node->cd)
-                       node->used = FALSE;
-               else
-                       iconv_close (cd);
-       } else {
-               ICONV_CACHE_UNLOCK ();
-               
-               d(g_warning ("This iconv context wasn't opened using g_mime_iconv_open()"));
-               
-               return iconv_close (cd);
-       }
-       
-       ICONV_CACHE_UNLOCK ();
-       
-       return 0;
+       return iconv_close (cd);
 }
diff --git a/gmime/gmime-iconv.h b/gmime/gmime-iconv.h
index fd381c6..e5bc0fb 100644
--- a/gmime/gmime-iconv.h
+++ b/gmime/gmime-iconv.h
@@ -27,11 +27,9 @@
 
 G_BEGIN_DECLS
 
-void g_mime_iconv_init (void);
-void g_mime_iconv_shutdown (void);
-
 iconv_t g_mime_iconv_open (const char *to, const char *from);
 
+int g_mime_iconv_close (iconv_t cd);
 
 /**
  * g_mime_iconv:
@@ -98,8 +96,6 @@ iconv_t g_mime_iconv_open (const char *to, const char *from);
  **/
 #define g_mime_iconv(cd,inbuf,inleft,outbuf,outleft) iconv (cd, inbuf, inleft, outbuf, outleft)
 
-int g_mime_iconv_close (iconv_t cd);
-
 G_END_DECLS
 
 #endif /* __GMIME_ICONV_H__ */
diff --git a/gmime/gmime.c b/gmime/gmime.c
index 77cea63..54e6aae 100644
--- a/gmime/gmime.c
+++ b/gmime/gmime.c
@@ -49,8 +49,6 @@
  **/
 
 extern void g_mime_crypto_context_shutdown (void);
-extern void g_mime_iconv_utils_shutdown (void);
-extern void g_mime_iconv_utils_init (void);
 
 GQuark gmime_gpgme_error_quark;
 GQuark gmime_error_quark;
@@ -119,8 +117,6 @@ g_mime_init (void)
        g_mime_format_options_init ();
        g_mime_parser_options_init ();
        g_mime_charset_map_init ();
-       g_mime_iconv_utils_init ();
-       g_mime_iconv_init ();
        
 #ifdef ENABLE_CRYPTO
        /* gpgme_check_version() initializes GpgMe */
@@ -217,8 +213,7 @@ g_mime_init (void)
 /**
  * g_mime_shutdown:
  *
- * Frees internally allocated tables created in g_mime_init(). Also
- * calls g_mime_charset_map_shutdown() and g_mime_iconv_shutdown().
+ * Frees internally allocated tables created in g_mime_init().
  **/
 void
 g_mime_shutdown (void)
@@ -231,6 +226,4 @@ g_mime_shutdown (void)
        g_mime_format_options_shutdown ();
        g_mime_parser_options_shutdown ();
        g_mime_charset_map_shutdown ();
-       g_mime_iconv_utils_shutdown ();
-       g_mime_iconv_shutdown ();
 }
diff --git a/tests/test-iconv.c b/tests/test-iconv.c
index 1f699b7..1ab51d0 100644
--- a/tests/test-iconv.c
+++ b/tests/test-iconv.c
@@ -33,78 +33,6 @@
 /*#define ENABLE_ZENTIMER*/
 #include "zentimer.h"
 
-#ifdef TEST_CACHE
-static char *charsets[] = {
-       "iso-8859-1",
-       "iso-8859-2",
-       "iso-8859-4",
-       "iso-8859-5",
-       "iso-8859-7",
-       "iso-8859-8",
-       "iso-8859-9",
-       "iso-8859-13",
-       "iso-8859-15",
-       "koi8-r",
-       "koi8-u",
-       "windows-1250",
-       "windows-1251",
-       "windows-1252",
-       "windows-1253",
-       "windows-1254",
-       "windows-1255",
-       "windows-1256",
-       "windows-1257",
-       "euc-kr",
-       "euc-jp",
-       "iso-2022-kr",
-       "iso-2022-jp",
-       "utf-8",
-};
-
-static void
-test_cache (void)
-{
-       GSList *node, *next, *open_cds = NULL;
-       iconv_t cd;
-       int i;
-       
-       srand (time (NULL));
-       
-       for (i = 0; i < 5000; i++) {
-               const char *from, *to;
-               int which;
-               
-               which = rand () % G_N_ELEMENTS (charsets);
-               from = charsets[which];
-               which = rand () % G_N_ELEMENTS (charsets);
-               to = charsets[which];
-               
-               cd = g_mime_iconv_open (from, to);
-               if (cd == (iconv_t) -1) {
-                       g_warning ("%d: failed to open converter for %s to %s",
-                                  i, from, to);
-                       continue;
-               }
-               
-               which = rand () % 3;
-               if (!which) {
-                       g_mime_iconv_close (cd);
-               } else {
-                       open_cds = g_slist_prepend (open_cds, cd);
-               }
-       }
-       
-       node = open_cds;
-       while (node) {
-               next = node->next;
-               cd = node->data;
-               g_mime_iconv_close (cd);
-               g_slist_free_1 (node);
-               node = next;
-       }
-}
-#endif /* TEST_CACHE */
-
 
 struct {
        const char *text;
@@ -206,20 +134,13 @@ test_utils (void)
 
 int main (int argc, char **argv)
 {
-       g_mime_iconv_init ();
+       g_mime_init ();
        
        testsuite_init (argc, argv);
        
-#ifdef TEST_CACHE
-       ZenTimerStart (NULL);
-       test_cache ();
-       ZenTimerStop (NULL);
-       ZenTimerReport (NULL, "test_cache()");
-#endif
-       
        test_utils ();
        
-       g_mime_iconv_shutdown ();
+       g_mime_shutdown ();
        
        return testsuite_exit ();
 }
diff --git a/util/Makefile.am b/util/Makefile.am
index 16cb00b..50ce839 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -11,12 +11,8 @@ AM_CPPFLAGS = -I$(top_srcdir)                \
        $(GLIB_CFLAGS)
 
 libutil_la_SOURCES =                   \
-       cache.c                         \
-       cache.h                         \
        gtrie.c                         \
        gtrie.h                         \
-       list.c                          \
-       list.h                          \
        packed.c                        \
        packed.h                        \
        url-scanner.c                   \


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]