diff options
author | Andy Wingo <wingo@pobox.com> | 2012-02-14 14:30:48 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2012-02-17 12:11:35 +0100 |
commit | 8dfb7bbfd908ca883d0fdd0d868e13e6b20803ae (patch) | |
tree | a9de6d013851758e47cab732e79039b51c44187a /libguile/ports.c | |
parent | 6a97b1f93aace5c7c976aef51d36b3ae9cfd5630 (diff) | |
download | guile-8dfb7bbfd908ca883d0fdd0d868e13e6b20803ae.tar.gz |
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.
Diffstat (limited to 'libguile/ports.c')
-rw-r--r-- | libguile/ports.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/libguile/ports.c b/libguile/ports.c index 18607514c..414ea9400 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -882,7 +882,9 @@ open_iconv_descriptors (const char *encoding, int reading, int writing) allocation. */ scm_gc_register_allocation (16 * 1024); + scm_i_lock_iconv (); input_cd = iconv_open ("UTF-8", encoding); + scm_i_unlock_iconv (); if (input_cd == (iconv_t) -1) goto invalid_encoding; } @@ -893,11 +895,15 @@ open_iconv_descriptors (const char *encoding, int reading, int writing) allocation. */ scm_gc_register_allocation (16 * 1024); + scm_i_lock_iconv (); output_cd = iconv_open (encoding, "UTF-8"); + scm_i_unlock_iconv (); if (output_cd == (iconv_t) -1) { + scm_i_lock_iconv (); if (input_cd != (iconv_t) -1) iconv_close (input_cd); + scm_i_unlock_iconv (); goto invalid_encoding; } } @@ -930,10 +936,12 @@ open_iconv_descriptors (const char *encoding, int reading, int writing) static void close_iconv_descriptors (scm_t_iconv_descriptors *id) { + scm_i_lock_iconv (); if (id->input_cd != (iconv_t) -1) iconv_close (id->input_cd); if (id->output_cd != (iconv_t) -1) iconv_close (id->output_cd); + scm_i_unlock_iconv (); id->input_cd = (void *) -1; id->output_cd = (void *) -1; } @@ -1937,10 +1945,12 @@ scm_ungetc_unlocked (scm_t_wchar c, SCM port) encoding = "ISO-8859-1"; len = sizeof (result_buf); + scm_i_lock_iconv (); result = u32_conv_to_encoding (encoding, (enum iconv_ilseq_handler) pt->ilseq_handler, (uint32_t *) &c, 1, NULL, result_buf, &len); + scm_i_unlock_iconv (); if (SCM_UNLIKELY (result == NULL || len == 0)) scm_encoding_error (FUNC_NAME, errno, |