summaryrefslogtreecommitdiff
path: root/libguile/ports.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2012-02-14 14:30:48 +0100
committerAndy Wingo <wingo@pobox.com>2012-02-17 12:11:35 +0100
commit8dfb7bbfd908ca883d0fdd0d868e13e6b20803ae (patch)
treea9de6d013851758e47cab732e79039b51c44187a /libguile/ports.c
parent6a97b1f93aace5c7c976aef51d36b3ae9cfd5630 (diff)
downloadguile-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.c10
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,