diff options
Diffstat (limited to 'libguile/strings.c')
-rw-r--r-- | libguile/strings.c | 93 |
1 files changed, 28 insertions, 65 deletions
diff --git a/libguile/strings.c b/libguile/strings.c index c13802664..6e3b0a347 100644 --- a/libguile/strings.c +++ b/libguile/strings.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996,1998,2000,2001, 2004, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1998,2000,2001, 2004, 2006, 2008, 2009 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,7 +30,6 @@ #include "libguile/strings.h" #include "libguile/deprecation.h" #include "libguile/validate.h" -#include "libguile/dynwind.h" @@ -118,7 +117,7 @@ make_stringbuf (size_t len) } else { - char *mem = scm_gc_malloc (len+1, "string"); + char *mem = scm_gc_malloc_pointerless (len + 1, "string"); mem[len] = '\0'; return scm_double_cell (STRINGBUF_TAG, (scm_t_bits) mem, (scm_t_bits) len, (scm_t_bits) 0); @@ -136,19 +135,6 @@ scm_i_take_stringbufn (char *str, size_t len) (scm_t_bits) len, (scm_t_bits) 0); } -SCM -scm_i_stringbuf_mark (SCM buf) -{ - return SCM_BOOL_F; -} - -void -scm_i_stringbuf_free (SCM buf) -{ - if (!STRINGBUF_INLINE (buf)) - scm_gc_free (STRINGBUF_OUTLINE_CHARS (buf), - STRINGBUF_OUTLINE_LENGTH (buf) + 1, "string"); -} scm_i_pthread_mutex_t stringbuf_write_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER; @@ -306,20 +292,7 @@ scm_c_substring_shared (SCM str, size_t start, size_t end) return scm_i_substring_shared (str, start, end); } -SCM -scm_i_string_mark (SCM str) -{ - if (IS_SH_STRING (str)) - return SH_STRING_STRING (str); - else - return STRING_STRINGBUF (str); -} - -void -scm_i_string_free (SCM str) -{ -} - + /* Internal accessors */ @@ -351,8 +324,7 @@ scm_i_string_writable_chars (SCM orig_str) scm_i_pthread_mutex_lock (&stringbuf_write_mutex); if (STRINGBUF_SHARED (buf)) { - /* Clone stringbuf. For this, we put all threads to sleep. - */ + /* Clone stringbuf. */ size_t len = STRING_LENGTH (str); SCM new_buf; @@ -363,11 +335,16 @@ scm_i_string_writable_chars (SCM orig_str) memcpy (STRINGBUF_CHARS (new_buf), STRINGBUF_CHARS (buf) + STRING_START (str), len); - scm_i_thread_put_to_sleep (); - SET_STRING_STRINGBUF (str, new_buf); start -= STRING_START (str); + + /* FIXME: The following operations are not atomic, so other threads + looking at STR may see an inconsistent state. Nevertheless it can't + hurt much since (i) accessing STR while it is being mutated can't + yield a crash, and (ii) concurrent accesses to STR should be + protected by a mutex at the application level. The latter may not + apply when STR != ORIG_STR, though. */ SET_STRING_START (str, 0); - scm_i_thread_wake_up (); + SET_STRING_STRINGBUF (str, new_buf); buf = new_buf; @@ -433,8 +410,8 @@ scm_i_c_make_symbol (const char *name, size_t len, SCM buf = make_stringbuf (len); memcpy (STRINGBUF_CHARS (buf), name, len); - return scm_double_cell (scm_tc7_symbol | flags, SCM_UNPACK (buf), - (scm_t_bits) hash, SCM_UNPACK (props)); + return scm_immutable_double_cell (scm_tc7_symbol | flags, SCM_UNPACK (buf), + (scm_t_bits) hash, SCM_UNPACK (props)); } /* Return a new symbol that uses the LEN bytes pointed to by NAME as its @@ -473,18 +450,6 @@ scm_i_symbol_chars (SCM sym) } SCM -scm_i_symbol_mark (SCM sym) -{ - scm_gc_mark (SYMBOL_STRINGBUF (sym)); - return SCM_CELL_OBJECT_3 (sym); -} - -void -scm_i_symbol_free (SCM sym) -{ -} - -SCM scm_i_symbol_substring (SCM sym, size_t start, size_t end) { SCM buf = SYMBOL_STRINGBUF (sym); @@ -983,6 +948,7 @@ scm_makfromstrs (int argc, char **argv) char ** scm_i_allocate_string_pointers (SCM list) +#define FUNC_NAME "scm_i_allocate_string_pointers" { char **result; int len = scm_ilength (list); @@ -991,34 +957,31 @@ scm_i_allocate_string_pointers (SCM list) if (len < 0) scm_wrong_type_arg_msg (NULL, 0, list, "proper list"); - scm_dynwind_begin (0); - - result = (char **) scm_malloc ((len + 1) * sizeof (char *)); + result = scm_gc_malloc ((len + 1) * sizeof (char *), + "string pointers"); result[len] = NULL; - scm_dynwind_unwind_handler (free, result, 0); /* The list might be have been modified in another thread, so we check LIST before each access. */ for (i = 0; i < len && scm_is_pair (list); i++) { - result[i] = scm_to_locale_string (SCM_CAR (list)); + SCM str; + size_t len; + + str = SCM_CAR (list); + len = scm_c_string_length (str); + + result[i] = scm_gc_malloc_pointerless (len + 1, "string pointers"); + memcpy (result[i], scm_i_string_chars (str), len); + result[i][len] = '\0'; + list = SCM_CDR (list); } - scm_dynwind_end (); return result; } - -void -scm_i_free_string_pointers (char **pointers) -{ - int i; - - for (i = 0; pointers[i]; i++) - free (pointers[i]); - free (pointers); -} +#undef FUNC_NAME void scm_i_get_substring_spec (size_t len, |