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 ---