diff options
| author | Noam Postavsky | 2016-12-11 13:08:15 -0500 |
|---|---|---|
| committer | Noam Postavsky | 2016-12-12 21:20:33 -0500 |
| commit | f66174a1b7f8e87e699ecf629563244782291148 (patch) | |
| tree | 9f70e9c40b4ddf57c363300826e155c83583a6ba /src | |
| parent | 8db7b65d66f01e90a05cc9f11c67667233d84ca0 (diff) | |
| download | emacs-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.c | 46 | ||||
| -rw-r--r-- | src/eval.c | 51 | ||||
| -rw-r--r-- | src/lisp.h | 6 |
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 | ||
| 1637 | DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0, | 1639 | void |
| 1638 | doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated. | 1640 | set_default_internal (Lisp_Object symbol, Lisp_Object value, |
| 1639 | The default value is seen in buffers that do not have their own values | 1641 | enum Set_Internal_Bind bindflag) |
| 1640 | for 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 | ||
| 1720 | DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0, | ||
| 1721 | doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated. | ||
| 1722 | The default value is seen in buffers that do not have their own values | ||
| 1723 | for this variable. */) | ||
| 1724 | (Lisp_Object symbol, Lisp_Object value) | ||
| 1725 | { | ||
| 1726 | set_default_internal (symbol, value, SET_INTERNAL_SET); | ||
| 1727 | return value; | ||
| 1728 | } | ||
| 1729 | |||
| 1718 | DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0, | 1730 | DEFUN ("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. |
| 1720 | VAR, the variable name, is literal (not evaluated); | 1732 | VAR, 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 | ||
| 3198 | static void | 3198 | static void |
| 3199 | do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, | 3199 | do_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 | ||
| 3372 | static void | 3364 | static void |
| 3373 | do_one_unbind (union specbinding *this_binding, bool unwinding) | 3365 | do_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 *); | |||
| 3493 | enum Set_Internal_Bind { | 3493 | enum 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 | }; |
| 3498 | extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, | 3499 | extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, |
| 3499 | enum Set_Internal_Bind); | 3500 | enum Set_Internal_Bind); |
| 3501 | extern void set_default_internal (Lisp_Object, Lisp_Object, | ||
| 3502 | enum Set_Internal_Bind bindflag); | ||
| 3503 | |||
| 3500 | extern void syms_of_data (void); | 3504 | extern void syms_of_data (void); |
| 3501 | extern void swap_in_global_binding (struct Lisp_Symbol *); | 3505 | extern void swap_in_global_binding (struct Lisp_Symbol *); |
| 3502 | 3506 | ||