summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-09-26 01:08:29 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:59:15 -0500
commit4a1d53a07a5bb1b5a5c73eceb173225924a71ef5 (patch)
tree70fa01170de0de6cbc67495757476b7e6c3fb3bc
parent159f81ee32dbd7c832fb8c3723d0f0207d039078 (diff)
downloadsamba-4a1d53a07a5bb1b5a5c73eceb173225924a71ef5.tar.gz
samba-4a1d53a07a5bb1b5a5c73eceb173225924a71ef5.tar.bz2
samba-4a1d53a07a5bb1b5a5c73eceb173225924a71ef5.zip
r2638: do lazy initialisation of iconv handles, so we don't initialise a
handle unless we use it. This saves quite a bit of memory (libc chews a lot loading a handle). Typically smbd now loads 3 handles, instead of 36. (This used to be commit 60e8d154fda548862cd6f8e8c1dadd64b3c4bd9c)
-rw-r--r--source4/lib/charcnv.c68
1 files changed, 29 insertions, 39 deletions
diff --git a/source4/lib/charcnv.c b/source4/lib/charcnv.c
index fd550895d0..3a3d470f99 100644
--- a/source4/lib/charcnv.c
+++ b/source4/lib/charcnv.c
@@ -37,9 +37,6 @@
* @sa lib/iconv.c
*/
-static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS];
-
-
/**
* Return the name of a charset to give to iconv().
**/
@@ -66,55 +63,48 @@ static void lazy_initialize_conv(void)
initialized = True;
load_case_tables();
init_iconv();
- init_valid_table();
}
}
-/**
- Initialize iconv conversion descriptors.
-**/
-void init_iconv(void)
+static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS];
+
+/*
+ on-demand initialisation of conversion handles
+*/
+static smb_iconv_t get_conv_handle(charset_t from, charset_t to)
{
- int c1, c2;
- BOOL did_reload = False;
+ const char *n1, *n2;
- /* so that charset_name() works we need to get the UNIX<->UCS2 going
- first */
- if (!conv_handles[CH_UNIX][CH_UTF16])
- conv_handles[CH_UNIX][CH_UTF16] = smb_iconv_open(charset_name(CH_UTF16),
- "ASCII");
+ if (conv_handles[from][to]) {
+ return conv_handles[from][to];
+ }
- if (!conv_handles[CH_UTF16][CH_UNIX])
- conv_handles[CH_UTF16][CH_UNIX] = smb_iconv_open("ASCII",
- charset_name(CH_UTF16));
+ n1 = charset_name(from);
+ n2 = charset_name(to);
+ conv_handles[from][to] = smb_iconv_open(n2,n1);
+
+ return conv_handles[from][to];
+}
+
+/**
+ re-initialize iconv conversion descriptors
+**/
+void init_iconv(void)
+{
+ charset_t c1, c2;
for (c1=0;c1<NUM_CHARSETS;c1++) {
for (c2=0;c2<NUM_CHARSETS;c2++) {
- const char *n1 = charset_name((charset_t)c1);
- const char *n2 = charset_name((charset_t)c2);
- if (conv_handles[c1][c2] &&
- strcmp(n1, conv_handles[c1][c2]->from_name) == 0 &&
- strcmp(n2, conv_handles[c1][c2]->to_name) == 0)
- continue;
-
- did_reload = True;
-
- if (conv_handles[c1][c2])
- smb_iconv_close(conv_handles[c1][c2]);
-
- conv_handles[c1][c2] = smb_iconv_open(n2,n1);
- if (conv_handles[c1][c2] == (smb_iconv_t)-1) {
- DEBUG(0,("Conversion from %s to %s not supported\n",
- charset_name((charset_t)c1), charset_name((charset_t)c2)));
+ if (conv_handles[c1][c2] != NULL) {
+ if (conv_handles[c1][c2] != -1) {
+ smb_iconv_close(conv_handles[c1][c2]);
+ }
conv_handles[c1][c2] = NULL;
}
}
}
- if (did_reload) {
- init_valid_table();
- }
}
/**
@@ -141,7 +131,7 @@ ssize_t convert_string(charset_t from, charset_t to,
lazy_initialize_conv();
- descriptor = conv_handles[from][to];
+ descriptor = get_conv_handle(from, to);
if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
/* conversion not supported, use as is */
@@ -206,7 +196,7 @@ ssize_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
lazy_initialize_conv();
- descriptor = conv_handles[from][to];
+ descriptor = get_conv_handle(from, to);
if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
/* conversion not supported, return -1*/