]> git.eshelyaron.com Git - emacs.git/commitdiff
Unbind thread-bound variables when the thread is terminated.
authorGiuseppe Scrivano <gscrivano@gnu.org>
Sun, 3 Jan 2010 13:58:50 +0000 (14:58 +0100)
committerGiuseppe Scrivano <gscrivano@gnu.org>
Sun, 3 Jan 2010 13:58:50 +0000 (14:58 +0100)
src/data.c
src/lisp.h
src/thread.c

index 96c77124c5799283f3291cbb1b5fc86dbe37814e..a5a317c3d2e089771fbef2b6ea11590f5411b907 100644 (file)
@@ -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);
                       }
                   }
               }
index 556d00e803bd6c35d1047f30295c748f7e1dfd34..b566a2920ecba45310811a42f03850ee1eb53a72 100644 (file)
@@ -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);
index 5c5e0f22ca3f203445a68df7fe4b4830bcbd2a1e..6381640dec48b63a088cb06b836fd957693a5062 100644 (file)
@@ -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)
     ;