From 405bb3c03967322f12ca33e6ed52161ce7172d29 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 3 Jan 2010 14:58:50 +0100 Subject: [PATCH] Unbind thread-bound variables when the thread is terminated. --- src/data.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/lisp.h | 1 + src/thread.c | 2 ++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/data.c b/src/data.c index 96c77124c57..a5a317c3d2e 100644 --- a/src/data.c +++ b/src/data.c @@ -837,7 +837,7 @@ blocal_get_thread_data (struct Lisp_Buffer_Local_Value *l) XSETFASTINT (len, 4); ret = Fmake_vector (len, Qnil); - + if (NILP (parent)) XSETFASTINT (AREF (ret, 0), 0); else @@ -860,6 +860,47 @@ blocal_get_thread_data (struct Lisp_Buffer_Local_Value *l) return &XCDR_AS_LVALUE (ret); } +/* Remove any thread-local data. */ +void +blocal_unbind_thread (Lisp_Object thread) +{ + struct buffer *b; + EMACS_UINT i; + struct Lisp_Vector *obarray = XVECTOR (Vobarray); + for (i = 0; i < obarray->size; i++) + { + struct Lisp_Symbol *sym; + + if (!SYMBOLP (obarray->contents[i])) + continue; + + sym = XSYMBOL (obarray->contents[i]); + +#define UNBIND_LOCAL_VALUE(X) do { \ + Lisp_Object tem = assq_no_quit (thread, (X)); \ + if (!NILP (tem)) \ + (X) = Fdelq (tem, (X)); \ + } while (0) + + if (BUFFER_LOCAL_VALUEP (SYMBOL_VALUE (obarray->contents[i]))) + { + struct Lisp_Buffer_Local_Value *loc + = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (obarray->contents[i])); + + UNBIND_LOCAL_VALUE (loc->realvalue); + UNBIND_LOCAL_VALUE (loc->thread_data); + } + + if (THREADLOCALP (SYMBOL_VALUE (obarray->contents[i]))) + { + struct Lisp_ThreadLocal *val + = XTHREADLOCAL (SYMBOL_VALUE (obarray->contents[i])); + UNBIND_LOCAL_VALUE (val->thread_alist); + } + } +#undef UNBIND_LOCAL_VALUE +} + void blocal_set_thread_data (struct Lisp_Buffer_Local_Value *l, Lisp_Object obj) { @@ -1155,7 +1196,7 @@ store_symval_forwarding (symbol, valcontents, newval, buf) Fsetcdr (assq_no_quit (XCAR (XCAR (it)), XTHREADLOCAL (rv)->thread_alist), newval); - XSETCDR (XCAR (BLOCAL_CDR_VEC (head), newval); + XSETCDR (XCAR (BLOCAL_CDR_VEC (head)), newval); } } } diff --git a/src/lisp.h b/src/lisp.h index 556d00e803b..b566a2920ec 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1365,6 +1365,7 @@ struct Lisp_Buffer_Local_Value Lisp_Object thread_data; }; +void blocal_unbind_thread (Lisp_Object thread); Lisp_Object *blocal_get_thread_data (struct Lisp_Buffer_Local_Value *l); void blocal_set_thread_data (struct Lisp_Buffer_Local_Value *l, Lisp_Object o); Lisp_Object *blocal_getrealvalue (struct Lisp_Buffer_Local_Value *l); diff --git a/src/thread.c b/src/thread.c index 5c5e0f22ca3..6381640dec4 100644 --- a/src/thread.c +++ b/src/thread.c @@ -238,6 +238,8 @@ run_thread (void *state) /* It might be nice to do something with errors here. */ internal_condition_case (invoke_thread_function, Qt, do_nothing); + blocal_unbind_thread (current_thread); + /* Unlink this thread from the list of all threads. */ for (iter = &all_threads; *iter != self; iter = &(*iter)->next_thread) ; -- 2.39.5