From af6252f00326542cfa052ec9c2a99477cd1b1d7e Mon Sep 17 00:00:00 2001 From: Clinton Ebadi Date: Sat, 17 Apr 2010 14:23:16 -0400 Subject: [PATCH 3/3] Reference weak vectors with the allocator lock held * libguile/vectors.c (do_weak_vector_ref): New function. (scm_c_vector_ref): Call `do_weak_vector_ref' with the allocator lock held when referencing weak vectors. --- libguile/vectors.c | 54 ++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 40 insertions(+), 14 deletions(-) diff --git a/libguile/vectors.c b/libguile/vectors.c index cca57cd..5788ec1 100644 --- a/libguile/vectors.c +++ b/libguile/vectors.c @@ -202,22 +202,46 @@ scm_vector_ref (SCM v, SCM k) } #undef FUNC_NAME +struct t_weak_vector_ref_args +{ + SCM vector; + size_t k; +}; + +/* Accessing weak pointers *must* be done with the allocator lock held. */ +static void * +do_weak_vector_ref (void* data) +{ + struct t_weak_vector_ref_args *args = (struct t_weak_vector_ref_args *) data; + register SCM elt = (SCM_I_VECTOR_ELTS(args->vector))[args->k]; + + if (elt == SCM_PACK (NULL)) + /* ELT was a weak pointer and got nullified by the GC. */ + return SCM_BOOL_F; + + return elt; +} + SCM scm_c_vector_ref (SCM v, size_t k) { if (SCM_I_IS_VECTOR (v)) { - register SCM elt; - if (k >= SCM_I_VECTOR_LENGTH (v)) scm_out_of_range (NULL, scm_from_size_t (k)); - elt = (SCM_I_VECTOR_ELTS(v))[k]; - if ((elt == SCM_PACK (NULL)) && SCM_I_WVECTP (v)) - /* ELT was a weak pointer and got nullified by the GC. */ - return SCM_BOOL_F; + if (SCM_I_WVECTP (v) && !SCM_IS_WHVEC (v)) + { + struct t_weak_vector_ref_args args; + args.vector = v; + args.k = k; - return elt; + return GC_call_with_alloc_lock (do_weak_vector_ref, &args); + } + else + { + return (SCM_I_VECTOR_ELTS(v))[k]; + } } else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1) { @@ -225,18 +249,20 @@ scm_c_vector_ref (SCM v, size_t k) SCM vv = SCM_I_ARRAY_V (v); if (SCM_I_IS_VECTOR (vv)) { - register SCM elt; - if (k >= dim->ubnd - dim->lbnd + 1) scm_out_of_range (NULL, scm_from_size_t (k)); k = SCM_I_ARRAY_BASE (v) + k*dim->inc; - elt = (SCM_I_VECTOR_ELTS (vv))[k]; - if ((elt == SCM_PACK (NULL)) && (SCM_I_WVECTP (vv))) - /* ELT was a weak pointer and got nullified by the GC. */ - return SCM_BOOL_F; + if (SCM_I_WVECTP (vv) && !SCM_IS_WHVEC (vv)) + { + struct t_weak_vector_ref_args args; + args.vector = vv; + args.k = k; + + return GC_call_with_alloc_lock (do_weak_vector_ref, &args); + } - return elt; + return (SCM_I_VECTOR_ELTS (vv))[k]; } scm_wrong_type_arg_msg (NULL, 0, v, "non-uniform vector"); } -- 1.6.5.7