1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-07-05 09:10:18 +02:00

wrap iconv_open / iconv_close with a lock to help in thread/fork issues

* libguile/bytevectors.c (STRING_TO_UTF, scm_string_to_utf8)
  (UTF_TO_STRING):
* libguile/ports.c (open_iconv_descriptors, close_iconv_descriptors):
* libguile/strings.c (scm_from_stringn, scm_to_stringn): Wrap operations
  that acquire and destroy iconv contexts with a mutex.  While iconv is
  threadsafe, internally it uses a lock, and we need to make sure when
  we fork() that no one has that lock -- so we surround it with another
  one.  Gross.
This commit is contained in:
Andy Wingo 2012-02-14 14:30:48 +01:00
parent 7329a5dba1
commit 86150ed040
4 changed files with 42 additions and 1 deletions

View file

@ -225,7 +225,22 @@ narrow_stringbuf (SCM buf)
return new_buf;
}
scm_i_pthread_mutex_t stringbuf_write_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
static scm_i_pthread_mutex_t iconv_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
void
scm_i_lock_iconv (void)
{
scm_i_pthread_mutex_lock (&iconv_mutex);
}
void
scm_i_unlock_iconv (void)
{
scm_i_pthread_mutex_unlock (&iconv_mutex);
}
/* Copy-on-write strings.
@ -1530,12 +1545,14 @@ scm_from_stringn (const char *str, size_t len, const char *encoding,
return scm_from_utf8_stringn (str, len);
u32len = 0;
scm_i_lock_iconv ();
u32 = (scm_t_wchar *) u32_conv_from_encoding (encoding,
(enum iconv_ilseq_handler)
handler,
str, len,
NULL,
NULL, &u32len);
scm_i_unlock_iconv ();
if (SCM_UNLIKELY (u32 == NULL))
decoding_error (__func__, errno, str, len);
@ -2070,10 +2087,12 @@ scm_to_stringn (SCM str, size_t *lenp, const char *encoding,
enc = "ISO-8859-1";
if (scm_i_is_narrow_string (str))
{
scm_i_lock_iconv ();
ret = mem_iconveh (scm_i_string_chars (str), ilen,
"ISO-8859-1", enc,
(enum iconv_ilseq_handler) handler, NULL,
&buf, &len);
scm_i_unlock_iconv ();
if (ret != 0)
scm_encoding_error (__func__, errno,
@ -2084,12 +2103,14 @@ scm_to_stringn (SCM str, size_t *lenp, const char *encoding,
}
else
{
scm_i_lock_iconv ();
buf = u32_conv_to_encoding (enc,
(enum iconv_ilseq_handler) handler,
(scm_t_uint32 *) scm_i_string_wide_chars (str),
ilen,
NULL,
NULL, &len);
scm_i_unlock_iconv ();
if (buf == NULL)
scm_encoding_error (__func__, errno,
"cannot convert wide string to output locale",
@ -2333,6 +2354,7 @@ scm_init_strings ()
{
scm_nullstr = scm_i_make_string (0, NULL, 0);
scm_c_atfork_lock_static_mutex (&iconv_mutex);
scm_c_atfork_lock_static_mutex (&stringbuf_write_mutex);
#include "libguile/strings.x"