summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Gran <spk121@yahoo.com>2009-08-19 21:47:19 -0700
committerMichael Gran <spk121@yahoo.com>2009-08-19 22:15:41 -0700
commit06b961904de0c3007763b0e5bd21cc9f8afebe76 (patch)
treeff5a4422fadab58b77cb551ad9a2d7185c2ebb08
parent2759c092d0fe200dd5abee9b1e8a7f5123e25e5d (diff)
downloadguile-06b961904de0c3007763b0e5bd21cc9f8afebe76.tar.gz
Avoid possible mutex hang on error message output
Avoid possible mutex hang when scm_lfwrite_substr is used in error message output and when an error has caused the stringbuf write mutex to not be unlocked. scm_lfwrite_substr makes a substring: making a substring requires that mutex. Hopefully, all cases of non-local jumps when the stringbuf write lock is held have been eliminated anyway, making this O.B.E. * libguile/ports.c (scm_lfwrite_str): include functionality in this function instead of making this a special case of scm_lfwrite_substr
-rw-r--r--libguile/ports.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/libguile/ports.c b/libguile/ports.c
index 60b21dd41..1ddeaa364 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -1023,6 +1023,9 @@ scm_lfwrite_substr (SCM str, size_t start, size_t end, SCM port)
end = size;
size = end - start;
+ /* Note that making a substring will likely take the
+ stringbuf_write_mutex. So, one shouldn't use scm_lfwrite_substr
+ if the stringbuf write mutex may still be held elsewhere. */
buf = scm_to_stringn (scm_c_substring (str, start, end), &len,
NULL, SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE);
ptob->write (port, buf, len);
@@ -1042,7 +1045,29 @@ scm_lfwrite_substr (SCM str, size_t start, size_t end, SCM port)
void
scm_lfwrite_str (SCM str, SCM port)
{
- scm_lfwrite_substr (str, 0, (size_t) (-1), port);
+ size_t i, size = scm_i_string_length (str);
+ scm_t_port *pt = SCM_PTAB_ENTRY (port);
+ scm_t_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)];
+ scm_t_wchar p;
+ char *buf;
+ size_t len;
+
+ if (pt->rw_active == SCM_PORT_READ)
+ scm_end_input (port);
+
+ buf = scm_to_stringn (str, &len,
+ NULL, SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE);
+ ptob->write (port, buf, len);
+ free (buf);
+
+ for (i = 0; i < size; i++)
+ {
+ p = scm_i_string_ref (str, i);
+ update_port_lf (p, port);
+ }
+
+ if (pt->rw_random)
+ pt->rw_active = SCM_PORT_WRITE;
}
/* scm_c_read