[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: unwind-protect not cleaning up?
Re: unwind-protect not cleaning up?
Sun, 01 Jul 2012 23:17:52 +0530
Gnus/5.13 (Gnus v5.13) Emacs/24.1 (windows-nt)
Eli Zaretskii <address@hidden> writes:
>> From: Jambunathan K <address@hidden>
>> Date: Sat, 30 Jun 2012 11:01:21 +0530
>> Cc: address@hidden
>> Nothing in the manual suggests that some sort of user-intervention
>> is required for recovery.
> Because no intervention is needed, in general. It's just that you
> tried to trigger the stack unwinding with something that signals an
> error and enters the debugger. Change your example to this:
> (let ((buffer (get-buffer-create "YOU CANNOT KILL ME")))
> (with-current-buffer buffer
> (let ((eval-expression-debug-on-error nil)
> (debug-on-signal nil))
> (/ 1 0)
> (kill-buffer buffer)))))
> and you will get what you expected without any user intervention.
`eval-expression-debug-on-error' and `debug-on-signal' (as used above)
is really too much of an information for a developer who is not working
in Emacs core. Though the above information is useful, it is unlikely
that a Random Joe developer will actually use it. So these need not be
>> May be I should be looking at someother API that "guarantees" cleanup
>> very much like unwind-protect, without the 'c' part.
>> I can use (condition-case VAR BODYFORM &rest HANDLERS) with the cleanup
>> happening both in BODYFORM and also in (error ) HANDLER. I felt that
>> unwind-protect construct is more elegant. Any suggestions...
> The popular use for unwind-protect is when the user could C-g inside
> the protected form. For errors such as division by zero,
> condition-case is indeed better, as you can run some code when the
> error is thrown.
>> Btw, if unwind-protect is behaving the right way, manpage needs an
> We don't have manpages in Emacs. Did you mean the manual? If so,
> what would you suggest to add/update there, in view of the above?
Here is my recommendation for "(elisp) Cleanups". Re-word it for
correctness or trim it for brevity.
If a (long-running) command allocates resources - processes or buffers -
for it's own work and it needs to be aborted mid-way (remember it is
long-running and the user might lose patience), then one should use an
unwind-protect with cleanup handlers. This way when the user aborts the
command with C-g the command is stopped cleanly.
A command could become long-running against developer's wishes. So
insert a cross-reference to (info "(elisp) Infinite Loops").
We can make the example simpler, with an actual infinite loop as below.
(let ((buffer (get-buffer-create " *temp*")))
(while t (ignore)) ;; hog the cpu
If `debug-on-quit' is nil, then on C-g cleanup forms are executed.
However, if `debug-on-quit' is t, continuing from the debugger with 'c'
will resume the protected form (and cleanup form will not be executed?)
I will also split the "Cleanups" in to two nodes. For want of better
names, let me call it "Cleanup on quit" and "Cleanup on error".
`unwind-protect' will go in the first node and `condition-case' in the
second node. (Manual goes an extra length to clarify that quit and
error are actually two different things.)
I also tried comparing `condition-case' with `unwind-protect'.
(error "Forced error")
((debug error) ;; ASSIGNMENT TO THE READER: add `quit' to this
;; list and see the behaviour on C-g with various
;; values of `debug-on-quit'. Particularly note
;; whether or not the handler is called.
(message "Released resources")))
With `debug' added to the list and `debug-on-error' set to `t', a
developer can examine the stacktrace and also trigger the cleanup with a
`c'. In other words, the cleanup happens irrespective of the value of
`debug-on-error'. (Compare this behaviour with C-g and `debug-on-quit',
search for ADDITIONAL NOTE above)
- Re: unwind-protect not cleaning up?,
Jambunathan K <=