aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNoam Postavsky2016-12-11 13:08:15 -0500
committerNoam Postavsky2016-12-12 21:20:33 -0500
commitf66174a1b7f8e87e699ecf629563244782291148 (patch)
tree9f70e9c40b4ddf57c363300826e155c83583a6ba /src
parent8db7b65d66f01e90a05cc9f11c67667233d84ca0 (diff)
downloademacs-f66174a1b7f8e87e699ecf629563244782291148.tar.gz
emacs-f66174a1b7f8e87e699ecf629563244782291148.zip
Clean up var watcher disabling on thread switching
* src/data.c (Fset_default): Move code into new C level function, `set_default_internal'. (set_default_internal): New function, like `Fset_default' but also takes additional bindflag parameter. (set_internal): Only call `notify_variable_watchers' if bindflag is not SET_INTERNAL_THREAD_SWITCH. * src/eval.c (do_specbind, do_one_unbind): Add bindflag parameter, passed on to set_internal and set_default_internal. Adjust callers. (rebind_for_thread_switch, unbind_for_thread_switch): Pass SET_INTERNAL_THREAD_SWITCH to do_specbind, do_one_unbind instead of temporarily adjusting symbol's trapped_write field.
Diffstat (limited to 'src')
-rw-r--r--src/data.c46
-rw-r--r--src/eval.c51
-rw-r--r--src/lisp.h6
3 files changed, 52 insertions, 51 deletions
diff --git a/src/data.c b/src/data.c
index 52cfe4ae4a3..6dd346bf8df 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1299,11 +1299,13 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1299 return; 1299 return;
1300 1300
1301 case SYMBOL_TRAPPED_WRITE: 1301 case SYMBOL_TRAPPED_WRITE:
1302 notify_variable_watchers (symbol, voide? Qnil : newval, 1302 /* Setting due to thread-switching doesn't count. */
1303 (bindflag == SET_INTERNAL_BIND? Qlet : 1303 if (bindflag != SET_INTERNAL_THREAD_SWITCH)
1304 bindflag == SET_INTERNAL_UNBIND? Qunlet : 1304 notify_variable_watchers (symbol, voide? Qnil : newval,
1305 voide? Qmakunbound : Qset), 1305 (bindflag == SET_INTERNAL_BIND? Qlet :
1306 where); 1306 bindflag == SET_INTERNAL_UNBIND? Qunlet :
1307 voide? Qmakunbound : Qset),
1308 where);
1307 /* FALLTHROUGH! */ 1309 /* FALLTHROUGH! */
1308 case SYMBOL_UNTRAPPED_WRITE: 1310 case SYMBOL_UNTRAPPED_WRITE:
1309 break; 1311 break;
@@ -1414,7 +1416,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1414 int offset = XBUFFER_OBJFWD (innercontents)->offset; 1416 int offset = XBUFFER_OBJFWD (innercontents)->offset;
1415 int idx = PER_BUFFER_IDX (offset); 1417 int idx = PER_BUFFER_IDX (offset);
1416 if (idx > 0 1418 if (idx > 0
1417 && !bindflag 1419 && bindflag == SET_INTERNAL_SET
1418 && !let_shadows_buffer_binding_p (sym)) 1420 && !let_shadows_buffer_binding_p (sym))
1419 SET_PER_BUFFER_VALUE_P (buf, idx, 1); 1421 SET_PER_BUFFER_VALUE_P (buf, idx, 1);
1420 } 1422 }
@@ -1634,11 +1636,9 @@ local bindings in certain buffers. */)
1634 xsignal1 (Qvoid_variable, symbol); 1636 xsignal1 (Qvoid_variable, symbol);
1635} 1637}
1636 1638
1637DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0, 1639void
1638 doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated. 1640set_default_internal (Lisp_Object symbol, Lisp_Object value,
1639The default value is seen in buffers that do not have their own values 1641 enum Set_Internal_Bind bindflag)
1640for this variable. */)
1641 (Lisp_Object symbol, Lisp_Object value)
1642{ 1642{
1643 struct Lisp_Symbol *sym; 1643 struct Lisp_Symbol *sym;
1644 1644
@@ -1652,11 +1652,13 @@ for this variable. */)
1652 xsignal1 (Qsetting_constant, symbol); 1652 xsignal1 (Qsetting_constant, symbol);
1653 else 1653 else
1654 /* Allow setting keywords to their own value. */ 1654 /* Allow setting keywords to their own value. */
1655 return value; 1655 return;
1656 1656
1657 case SYMBOL_TRAPPED_WRITE: 1657 case SYMBOL_TRAPPED_WRITE:
1658 /* Don't notify here if we're going to call Fset anyway. */ 1658 /* Don't notify here if we're going to call Fset anyway. */
1659 if (sym->redirect != SYMBOL_PLAINVAL) 1659 if (sym->redirect != SYMBOL_PLAINVAL
1660 /* Setting due to thread switching doesn't count. */
1661 && bindflag != SET_INTERNAL_THREAD_SWITCH)
1660 notify_variable_watchers (symbol, value, Qset_default, Qnil); 1662 notify_variable_watchers (symbol, value, Qset_default, Qnil);
1661 /* FALLTHROUGH! */ 1663 /* FALLTHROUGH! */
1662 case SYMBOL_UNTRAPPED_WRITE: 1664 case SYMBOL_UNTRAPPED_WRITE:
@@ -1669,7 +1671,7 @@ for this variable. */)
1669 switch (sym->redirect) 1671 switch (sym->redirect)
1670 { 1672 {
1671 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1673 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1672 case SYMBOL_PLAINVAL: return Fset (symbol, value); 1674 case SYMBOL_PLAINVAL: set_internal (symbol, value, Qnil, bindflag); return;
1673 case SYMBOL_LOCALIZED: 1675 case SYMBOL_LOCALIZED:
1674 { 1676 {
1675 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); 1677 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
@@ -1680,7 +1682,7 @@ for this variable. */)
1680 /* If the default binding is now loaded, set the REALVALUE slot too. */ 1682 /* If the default binding is now loaded, set the REALVALUE slot too. */
1681 if (blv->fwd && EQ (blv->defcell, blv->valcell)) 1683 if (blv->fwd && EQ (blv->defcell, blv->valcell))
1682 store_symval_forwarding (blv->fwd, value, NULL); 1684 store_symval_forwarding (blv->fwd, value, NULL);
1683 return value; 1685 return;
1684 } 1686 }
1685 case SYMBOL_FORWARDED: 1687 case SYMBOL_FORWARDED:
1686 { 1688 {
@@ -1706,15 +1708,25 @@ for this variable. */)
1706 if (!PER_BUFFER_VALUE_P (b, idx)) 1708 if (!PER_BUFFER_VALUE_P (b, idx))
1707 set_per_buffer_value (b, offset, value); 1709 set_per_buffer_value (b, offset, value);
1708 } 1710 }
1709 return value;
1710 } 1711 }
1711 else 1712 else
1712 return Fset (symbol, value); 1713 set_internal (symbol, value, Qnil, bindflag);
1714 return;
1713 } 1715 }
1714 default: emacs_abort (); 1716 default: emacs_abort ();
1715 } 1717 }
1716} 1718}
1717 1719
1720DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0,
1721 doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated.
1722The default value is seen in buffers that do not have their own values
1723for this variable. */)
1724 (Lisp_Object symbol, Lisp_Object value)
1725{
1726 set_default_internal (symbol, value, SET_INTERNAL_SET);
1727 return value;
1728}
1729
1718DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0, 1730DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0,
1719 doc: /* Set the default value of variable VAR to VALUE. 1731 doc: /* Set the default value of variable VAR to VALUE.
1720VAR, the variable name, is literal (not evaluated); 1732VAR, the variable name, is literal (not evaluated);
diff --git a/src/eval.c b/src/eval.c
index 7852ef700ba..0b257e2d9a0 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3197,7 +3197,7 @@ let_shadows_global_binding_p (Lisp_Object symbol)
3197 3197
3198static void 3198static void
3199do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, 3199do_specbind (struct Lisp_Symbol *sym, union specbinding *bind,
3200 Lisp_Object value) 3200 Lisp_Object value, enum Set_Internal_Bind bindflag)
3201{ 3201{
3202 switch (sym->redirect) 3202 switch (sym->redirect)
3203 { 3203 {
@@ -3205,19 +3205,19 @@ do_specbind (struct Lisp_Symbol *sym, union specbinding *bind,
3205 if (!sym->trapped_write) 3205 if (!sym->trapped_write)
3206 SET_SYMBOL_VAL (sym, value); 3206 SET_SYMBOL_VAL (sym, value);
3207 else 3207 else
3208 set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND); 3208 set_internal (specpdl_symbol (bind), value, Qnil, bindflag);
3209 break; 3209 break;
3210 3210
3211 case SYMBOL_FORWARDED: 3211 case SYMBOL_FORWARDED:
3212 if (BUFFER_OBJFWDP (SYMBOL_FWD (sym)) 3212 if (BUFFER_OBJFWDP (SYMBOL_FWD (sym))
3213 && specpdl_kind (bind) == SPECPDL_LET_DEFAULT) 3213 && specpdl_kind (bind) == SPECPDL_LET_DEFAULT)
3214 { 3214 {
3215 Fset_default (specpdl_symbol (bind), value); 3215 set_default_internal (specpdl_symbol (bind), value, bindflag);
3216 return; 3216 return;
3217 } 3217 }
3218 /* FALLTHROUGH */ 3218 /* FALLTHROUGH */
3219 case SYMBOL_LOCALIZED: 3219 case SYMBOL_LOCALIZED:
3220 set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND); 3220 set_internal (specpdl_symbol (bind), value, Qnil, bindflag);
3221 break; 3221 break;
3222 3222
3223 default: 3223 default:
@@ -3258,7 +3258,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3258 specpdl_ptr->let.old_value = SYMBOL_VAL (sym); 3258 specpdl_ptr->let.old_value = SYMBOL_VAL (sym);
3259 specpdl_ptr->let.saved_value = Qnil; 3259 specpdl_ptr->let.saved_value = Qnil;
3260 grow_specpdl (); 3260 grow_specpdl ();
3261 do_specbind (sym, specpdl_ptr - 1, value); 3261 do_specbind (sym, specpdl_ptr - 1, value, SET_INTERNAL_BIND);
3262 break; 3262 break;
3263 case SYMBOL_LOCALIZED: 3263 case SYMBOL_LOCALIZED:
3264 if (SYMBOL_BLV (sym)->frame_local) 3264 if (SYMBOL_BLV (sym)->frame_local)
@@ -3291,7 +3291,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3291 { 3291 {
3292 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; 3292 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT;
3293 grow_specpdl (); 3293 grow_specpdl ();
3294 do_specbind (sym, specpdl_ptr - 1, value); 3294 do_specbind (sym, specpdl_ptr - 1, value, SET_INTERNAL_BIND);
3295 return; 3295 return;
3296 } 3296 }
3297 } 3297 }
@@ -3299,7 +3299,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3299 specpdl_ptr->let.kind = SPECPDL_LET; 3299 specpdl_ptr->let.kind = SPECPDL_LET;
3300 3300
3301 grow_specpdl (); 3301 grow_specpdl ();
3302 do_specbind (sym, specpdl_ptr - 1, value); 3302 do_specbind (sym, specpdl_ptr - 1, value, SET_INTERNAL_BIND);
3303 break; 3303 break;
3304 } 3304 }
3305 default: emacs_abort (); 3305 default: emacs_abort ();
@@ -3354,23 +3354,16 @@ rebind_for_thread_switch (void)
3354 { 3354 {
3355 Lisp_Object value = specpdl_saved_value (bind); 3355 Lisp_Object value = specpdl_saved_value (bind);
3356 Lisp_Object sym = specpdl_symbol (bind); 3356 Lisp_Object sym = specpdl_symbol (bind);
3357 bool was_trapped =
3358 SYMBOLP (sym)
3359 && XSYMBOL (sym)->trapped_write == SYMBOL_TRAPPED_WRITE;
3360 /* FIXME: This is not clean, and if do_specbind signals an
3361 error, the symbol will be left untrapped. */
3362 if (was_trapped)
3363 XSYMBOL (sym)->trapped_write = SYMBOL_UNTRAPPED_WRITE;
3364 bind->let.saved_value = Qnil; 3357 bind->let.saved_value = Qnil;
3365 do_specbind (XSYMBOL (sym), bind, value); 3358 do_specbind (XSYMBOL (sym), bind, value,
3366 if (was_trapped) 3359 SET_INTERNAL_THREAD_SWITCH);
3367 XSYMBOL (sym)->trapped_write = SYMBOL_TRAPPED_WRITE;
3368 } 3360 }
3369 } 3361 }
3370} 3362}
3371 3363
3372static void 3364static void
3373do_one_unbind (union specbinding *this_binding, bool unwinding) 3365do_one_unbind (union specbinding *this_binding, bool unwinding,
3366 enum Set_Internal_Bind bindflag)
3374{ 3367{
3375 eassert (unwinding || this_binding->kind >= SPECPDL_LET); 3368 eassert (unwinding || this_binding->kind >= SPECPDL_LET);
3376 switch (this_binding->kind) 3369 switch (this_binding->kind)
@@ -3399,7 +3392,7 @@ do_one_unbind (union specbinding *this_binding, bool unwinding)
3399 SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding)); 3392 SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding));
3400 else 3393 else
3401 set_internal (sym, specpdl_old_value (this_binding), 3394 set_internal (sym, specpdl_old_value (this_binding),
3402 Qnil, SET_INTERNAL_UNBIND); 3395 Qnil, bindflag);
3403 break; 3396 break;
3404 } 3397 }
3405 else 3398 else
@@ -3409,8 +3402,9 @@ do_one_unbind (union specbinding *this_binding, bool unwinding)
3409 } 3402 }
3410 } 3403 }
3411 case SPECPDL_LET_DEFAULT: 3404 case SPECPDL_LET_DEFAULT:
3412 Fset_default (specpdl_symbol (this_binding), 3405 set_default_internal (specpdl_symbol (this_binding),
3413 specpdl_old_value (this_binding)); 3406 specpdl_old_value (this_binding),
3407 bindflag);
3414 break; 3408 break;
3415 case SPECPDL_LET_LOCAL: 3409 case SPECPDL_LET_LOCAL:
3416 { 3410 {
@@ -3422,7 +3416,7 @@ do_one_unbind (union specbinding *this_binding, bool unwinding)
3422 /* If this was a local binding, reset the value in the appropriate 3416 /* If this was a local binding, reset the value in the appropriate
3423 buffer, but only if that buffer's binding still exists. */ 3417 buffer, but only if that buffer's binding still exists. */
3424 if (!NILP (Flocal_variable_p (symbol, where))) 3418 if (!NILP (Flocal_variable_p (symbol, where)))
3425 set_internal (symbol, old_value, where, SET_INTERNAL_UNBIND); 3419 set_internal (symbol, old_value, where, bindflag);
3426 } 3420 }
3427 break; 3421 break;
3428 } 3422 }
@@ -3496,7 +3490,7 @@ unbind_to (ptrdiff_t count, Lisp_Object value)
3496 union specbinding this_binding; 3490 union specbinding this_binding;
3497 this_binding = *--specpdl_ptr; 3491 this_binding = *--specpdl_ptr;
3498 3492
3499 do_one_unbind (&this_binding, true); 3493 do_one_unbind (&this_binding, true, SET_INTERNAL_UNBIND);
3500 } 3494 }
3501 3495
3502 if (NILP (Vquit_flag) && !NILP (quitf)) 3496 if (NILP (Vquit_flag) && !NILP (quitf))
@@ -3515,17 +3509,8 @@ unbind_for_thread_switch (struct thread_state *thr)
3515 if ((--bind)->kind >= SPECPDL_LET) 3509 if ((--bind)->kind >= SPECPDL_LET)
3516 { 3510 {
3517 Lisp_Object sym = specpdl_symbol (bind); 3511 Lisp_Object sym = specpdl_symbol (bind);
3518 bool was_trapped =
3519 SYMBOLP (sym)
3520 && XSYMBOL (sym)->trapped_write == SYMBOL_TRAPPED_WRITE;
3521 bind->let.saved_value = find_symbol_value (sym); 3512 bind->let.saved_value = find_symbol_value (sym);
3522 /* FIXME: This is not clean, and if do_one_unbind signals an 3513 do_one_unbind (bind, false, SET_INTERNAL_THREAD_SWITCH);
3523 error, the symbol will be left untrapped. */
3524 if (was_trapped)
3525 XSYMBOL (sym)->trapped_write = SYMBOL_UNTRAPPED_WRITE;
3526 do_one_unbind (bind, false);
3527 if (was_trapped)
3528 XSYMBOL (sym)->trapped_write = SYMBOL_TRAPPED_WRITE;
3529 } 3514 }
3530 } 3515 }
3531} 3516}
diff --git a/src/lisp.h b/src/lisp.h
index 252707c3495..5b77dc8b7fd 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3493,10 +3493,14 @@ extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *);
3493enum Set_Internal_Bind { 3493enum Set_Internal_Bind {
3494 SET_INTERNAL_SET, 3494 SET_INTERNAL_SET,
3495 SET_INTERNAL_BIND, 3495 SET_INTERNAL_BIND,
3496 SET_INTERNAL_UNBIND 3496 SET_INTERNAL_UNBIND,
3497 SET_INTERNAL_THREAD_SWITCH
3497}; 3498};
3498extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, 3499extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object,
3499 enum Set_Internal_Bind); 3500 enum Set_Internal_Bind);
3501extern void set_default_internal (Lisp_Object, Lisp_Object,
3502 enum Set_Internal_Bind bindflag);
3503
3500extern void syms_of_data (void); 3504extern void syms_of_data (void);
3501extern void swap_in_global_binding (struct Lisp_Symbol *); 3505extern void swap_in_global_binding (struct Lisp_Symbol *);
3502 3506