diff options
author | Michael Gran <spk121@yahoo.com> | 2009-08-19 21:47:19 -0700 |
---|---|---|
committer | Michael Gran <spk121@yahoo.com> | 2009-08-19 22:15:41 -0700 |
commit | 06b961904de0c3007763b0e5bd21cc9f8afebe76 (patch) | |
tree | ff5a4422fadab58b77cb551ad9a2d7185c2ebb08 | |
parent | 2759c092d0fe200dd5abee9b1e8a7f5123e25e5d (diff) | |
download | guile-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.c | 27 |
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 |