citrus_iconv.c (cfe30d02adda7c3b5c76156ac52d50d8cab325d9) | citrus_iconv.c (ff0b75b897dde9a8455f0c199af9a75e424c38cc) |
---|---|
1/* $FreeBSD$ */ 2/* $NetBSD: citrus_iconv.c,v 1.7 2008/07/25 14:05:25 christos Exp $ */ 3 4/*- 5 * Copyright (c)2003 Citrus Project, 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 54 unchanged lines hidden (view full) --- 63#define CI_INITIAL_MAX_REUSE 5 64#define CI_ENV_MAX_REUSE "ICONV_MAX_REUSE" 65 66static bool isinit = false; 67static int shared_max_reuse, shared_num_unused; 68static _CITRUS_HASH_HEAD(, _citrus_iconv_shared, CI_HASH_SIZE) shared_pool; 69static TAILQ_HEAD(, _citrus_iconv_shared) shared_unused; 70 | 1/* $FreeBSD$ */ 2/* $NetBSD: citrus_iconv.c,v 1.7 2008/07/25 14:05:25 christos Exp $ */ 3 4/*- 5 * Copyright (c)2003 Citrus Project, 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 54 unchanged lines hidden (view full) --- 63#define CI_INITIAL_MAX_REUSE 5 64#define CI_ENV_MAX_REUSE "ICONV_MAX_REUSE" 65 66static bool isinit = false; 67static int shared_max_reuse, shared_num_unused; 68static _CITRUS_HASH_HEAD(, _citrus_iconv_shared, CI_HASH_SIZE) shared_pool; 69static TAILQ_HEAD(, _citrus_iconv_shared) shared_unused; 70 |
71static pthread_rwlock_t ci_lock = PTHREAD_RWLOCK_INITIALIZER; 72 |
|
71static __inline void 72init_cache(void) 73{ 74 | 73static __inline void 74init_cache(void) 75{ 76 |
75 WLOCK; | 77 WLOCK(&ci_lock); |
76 if (!isinit) { 77 _CITRUS_HASH_INIT(&shared_pool, CI_HASH_SIZE); 78 TAILQ_INIT(&shared_unused); 79 shared_max_reuse = -1; 80 if (!issetugid() && getenv(CI_ENV_MAX_REUSE)) 81 shared_max_reuse = atoi(getenv(CI_ENV_MAX_REUSE)); 82 if (shared_max_reuse < 0) 83 shared_max_reuse = CI_INITIAL_MAX_REUSE; 84 isinit = true; 85 } | 78 if (!isinit) { 79 _CITRUS_HASH_INIT(&shared_pool, CI_HASH_SIZE); 80 TAILQ_INIT(&shared_unused); 81 shared_max_reuse = -1; 82 if (!issetugid() && getenv(CI_ENV_MAX_REUSE)) 83 shared_max_reuse = atoi(getenv(CI_ENV_MAX_REUSE)); 84 if (shared_max_reuse < 0) 85 shared_max_reuse = CI_INITIAL_MAX_REUSE; 86 isinit = true; 87 } |
86 UNLOCK; | 88 UNLOCK(&ci_lock); |
87} 88 89static __inline void 90close_shared(struct _citrus_iconv_shared *ci) 91{ 92 93 if (ci) { 94 if (ci->ci_module) { --- 95 unchanged lines hidden (view full) --- 190 const char *src, const char *dst) 191{ 192 struct _citrus_iconv_shared * ci; 193 char convname[PATH_MAX]; 194 int hashval, ret = 0; 195 196 snprintf(convname, sizeof(convname), "%s/%s", src, dst); 197 | 89} 90 91static __inline void 92close_shared(struct _citrus_iconv_shared *ci) 93{ 94 95 if (ci) { 96 if (ci->ci_module) { --- 95 unchanged lines hidden (view full) --- 192 const char *src, const char *dst) 193{ 194 struct _citrus_iconv_shared * ci; 195 char convname[PATH_MAX]; 196 int hashval, ret = 0; 197 198 snprintf(convname, sizeof(convname), "%s/%s", src, dst); 199 |
198 WLOCK; | 200 WLOCK(&ci_lock); |
199 200 /* lookup alread existing entry */ 201 hashval = hash_func(convname); 202 _CITRUS_HASH_SEARCH(&shared_pool, ci, ci_hash_entry, match_func, 203 convname, hashval); 204 if (ci != NULL) { 205 /* found */ 206 if (ci->ci_used_count == 0) { --- 10 unchanged lines hidden (view full) --- 217 if (ret) 218 goto quit; 219 220 _CITRUS_HASH_INSERT(&shared_pool, ci, ci_hash_entry, hashval); 221 ci->ci_used_count = 1; 222 *rci = ci; 223 224quit: | 201 202 /* lookup alread existing entry */ 203 hashval = hash_func(convname); 204 _CITRUS_HASH_SEARCH(&shared_pool, ci, ci_hash_entry, match_func, 205 convname, hashval); 206 if (ci != NULL) { 207 /* found */ 208 if (ci->ci_used_count == 0) { --- 10 unchanged lines hidden (view full) --- 219 if (ret) 220 goto quit; 221 222 _CITRUS_HASH_INSERT(&shared_pool, ci, ci_hash_entry, hashval); 223 ci->ci_used_count = 1; 224 *rci = ci; 225 226quit: |
225 UNLOCK; | 227 UNLOCK(&ci_lock); |
226 227 return (ret); 228} 229 230static void 231release_shared(struct _citrus_iconv_shared * __restrict ci) 232{ 233 | 228 229 return (ret); 230} 231 232static void 233release_shared(struct _citrus_iconv_shared * __restrict ci) 234{ 235 |
234 WLOCK; | 236 WLOCK(&ci_lock); |
235 ci->ci_used_count--; 236 if (ci->ci_used_count == 0) { 237 /* put it into unused list */ 238 shared_num_unused++; 239 TAILQ_INSERT_TAIL(&shared_unused, ci, ci_tailq_entry); 240 /* flood out */ 241 while (shared_num_unused > shared_max_reuse) { 242 ci = TAILQ_FIRST(&shared_unused); 243 TAILQ_REMOVE(&shared_unused, ci, ci_tailq_entry); 244 _CITRUS_HASH_REMOVE(ci, ci_hash_entry); 245 shared_num_unused--; 246 close_shared(ci); 247 } 248 } 249 | 237 ci->ci_used_count--; 238 if (ci->ci_used_count == 0) { 239 /* put it into unused list */ 240 shared_num_unused++; 241 TAILQ_INSERT_TAIL(&shared_unused, ci, ci_tailq_entry); 242 /* flood out */ 243 while (shared_num_unused > shared_max_reuse) { 244 ci = TAILQ_FIRST(&shared_unused); 245 TAILQ_REMOVE(&shared_unused, ci, ci_tailq_entry); 246 _CITRUS_HASH_REMOVE(ci, ci_hash_entry); 247 shared_num_unused--; 248 close_shared(ci); 249 } 250 } 251 |
250 UNLOCK; | 252 UNLOCK(&ci_lock); |
251} 252 253/* 254 * _citrus_iconv_open: 255 * open a converter for the specified in/out codes. 256 */ 257int 258_citrus_iconv_open(struct _citrus_iconv * __restrict * __restrict rcv, --- 77 unchanged lines hidden --- | 253} 254 255/* 256 * _citrus_iconv_open: 257 * open a converter for the specified in/out codes. 258 */ 259int 260_citrus_iconv_open(struct _citrus_iconv * __restrict * __restrict rcv, --- 77 unchanged lines hidden --- |