[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Asynchronous bug
From: |
Richard Stallman |
Subject: |
Re: Asynchronous bug |
Date: |
Fri, 02 May 2003 03:06:42 -0400 |
Isn't this going to cause the unwind-protect to be re-executed
if a signal is thrown while executing
(*specpdl_ptr->func) (specpdl_ptr->old_value);
now that specpdl_ptr is decremented afterwards ?
Yes, you're right. How about this version?
Lisp_Object
unbind_to (count, value)
int count;
Lisp_Object value;
{
int quitf = !NILP (Vquit_flag);
struct gcpro gcpro1;
GCPRO1 (value);
Vquit_flag = Qnil;
while (specpdl_ptr != specpdl + count)
{
struct specbinding this_binding = *--specpdl_ptr;
if (this_binding.func != 0)
(*this_binding.func) (this_binding.old_value);
/* If the symbol is a list, it is really (SYMBOL WHERE
. CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
frame. If WHERE is a buffer or frame, this indicates we
bound a variable that had a buffer-local or frame-local
binding. WHERE nil means that the variable had the default
value when it was bound. CURRENT-BUFFER is the buffer that
was current when the variable was bound. */
else if (CONSP (this_binding.symbol))
{
Lisp_Object symbol, where;
symbol = XCAR (this_binding.symbol);
where = XCAR (XCDR (this_binding.symbol));
if (NILP (where))
Fset_default (symbol, this_binding.old_value);
else if (BUFFERP (where))
set_internal (symbol, this_binding.old_value, XBUFFER (where), 1);
else
set_internal (symbol, this_binding.old_value, NULL, 1);
}
else
{
/* If variable has a trivial value (no forwarding), we can
just set it. No need to check for constant symbols here,
since that was already done by specbind. */
if (!MISCP (SYMBOL_VALUE (this_binding.symbol)))
SET_SYMBOL_VALUE (this_binding.symbol, this_binding.old_value);
else
set_internal (this_binding.symbol, this_binding.old_value, 0, 1);
}
}
if (NILP (Vquit_flag) && quitf)
Vquit_flag = Qt;
UNGCPRO;
return value;
}