unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* unwind-protect not cleaning up?
@ 2012-06-30  0:54 Jambunathan K
  2012-06-30  2:07 ` Óscar Fuentes
  0 siblings, 1 reply; 6+ messages in thread
From: Jambunathan K @ 2012-06-30  0:54 UTC (permalink / raw)
  To: Emacs Devel


The snippet below is taken from (info "(elisp) Cleanups") with minor
modifications.  Put it in a scratch buffer and C-x C-e it.  Once it is
done, I am able to C-x b to YOU CANNOT KILL ME.

(let ((buffer (get-buffer-create "YOU CANNOT KILL ME")))
  (with-current-buffer buffer
    (unwind-protect
	(/ 1 0)
      (kill-buffer buffer))))

Comments...


In GNU Emacs 24.1.1 (i386-mingw-nt5.1.2600)
 of 2012-06-02 on MARVIN
Windowing system distributor `Microsoft Corp.', version 5.1.2600
Configured using:
 `configure --with-gcc (4.6) --no-opt --enable-checking --cflags
 -ID:/devel/emacs/libs/libXpm-3.5.8/include
 -ID:/devel/emacs/libs/libXpm-3.5.8/src
 -ID:/devel/emacs/libs/libpng-dev_1.4.3-1/include
 -ID:/devel/emacs/libs/zlib-dev_1.2.5-2/include
 -ID:/devel/emacs/libs/giflib-4.1.4-1/include
 -ID:/devel/emacs/libs/jpeg-6b-4/include
 -ID:/devel/emacs/libs/tiff-3.8.2-1/include
 -ID:/devel/emacs/libs/gnutls-3.0.9/include'

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: ENG
  value of $XMODIFIERS: nil
  locale-coding-system: cp1252
  default enable-multibyte-characters: t


-- 



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: unwind-protect not cleaning up?
  2012-06-30  0:54 unwind-protect not cleaning up? Jambunathan K
@ 2012-06-30  2:07 ` Óscar Fuentes
  2012-06-30  5:31   ` Jambunathan K
  0 siblings, 1 reply; 6+ messages in thread
From: Óscar Fuentes @ 2012-06-30  2:07 UTC (permalink / raw)
  To: emacs-devel

Jambunathan K <kjambunathan@gmail.com> writes:

> The snippet below is taken from (info "(elisp) Cleanups") with minor
> modifications.  Put it in a scratch buffer and C-x C-e it.  Once it is
> done, I am able to C-x b to YOU CANNOT KILL ME.
>
> (let ((buffer (get-buffer-create "YOU CANNOT KILL ME")))
>   (with-current-buffer buffer
>     (unwind-protect
> 	(/ 1 0)
>       (kill-buffer buffer))))
>
> Comments...

Here the debugger pops up with

Debugger entered--Lisp error: (arith-error)
  /(1 0)
  (unwind-protect (/ 1 0) (kill-buffer buffer))
  [...]

and then if I press `c' (for continuing) it goes away and there is no
trace left of the buffer previously created.

This looks correct to me. Do you see the debugger? Does the same thing
with emacs -Q ?

GNU Emacs 24.0.94.2 (x86_64-unknown-linux-gnu, X toolkit) of 2012-03-11





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: unwind-protect not cleaning up?
  2012-06-30  2:07 ` Óscar Fuentes
@ 2012-06-30  5:31   ` Jambunathan K
  2012-06-30  6:09     ` Eli Zaretskii
  0 siblings, 1 reply; 6+ messages in thread
From: Jambunathan K @ 2012-06-30  5:31 UTC (permalink / raw)
  To: Óscar Fuentes; +Cc: emacs-devel

Óscar Fuentes <ofv@wanadoo.es> writes:

> Jambunathan K <kjambunathan@gmail.com> writes:
>
>> The snippet below is taken from (info "(elisp) Cleanups") with minor
>> modifications.  Put it in a scratch buffer and C-x C-e it.  Once it is
>> done, I am able to C-x b to YOU CANNOT KILL ME.
>>
>> (let ((buffer (get-buffer-create "YOU CANNOT KILL ME")))
>>   (with-current-buffer buffer
>>     (unwind-protect
>> 	(/ 1 0)
>>       (kill-buffer buffer))))
>>
>> Comments...
>
> Here the debugger pops up with
>
> Debugger entered--Lisp error: (arith-error)
>   /(1 0)
>   (unwind-protect (/ 1 0) (kill-buffer buffer))
>   [...]
>
> and then if I press `c' (for continuing) it goes away and there is no
> trace left of the buffer previously created.
>
> This looks correct to me. Do you see the debugger? Does the same thing
> with emacs -Q ?
>
> GNU Emacs 24.0.94.2 (x86_64-unknown-linux-gnu, X toolkit) of
> 2012-03-11

Oh, Ok.

I get the same behaviour as you do.  Nothing in the manual suggests that
some sort of user-intervention is required for recovery.  Is
unwind-protect meant only for use be developers?  As someone who was
considering using this for the first time, I am confused by this
"user-intervention" behaviour.

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...

Btw, if unwind-protect is behaving the right way, manpage needs an
update...
-- 



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: unwind-protect not cleaning up?
  2012-06-30  5:31   ` Jambunathan K
@ 2012-06-30  6:09     ` Eli Zaretskii
  2012-07-01 17:47       ` Jambunathan K
  0 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2012-06-30  6:09 UTC (permalink / raw)
  To: Jambunathan K; +Cc: ofv, emacs-devel

> From: Jambunathan K <kjambunathan@gmail.com>
> Date: Sat, 30 Jun 2012 11:01:21 +0530
> Cc: emacs-devel@gnu.org
> 
> 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))
      (unwind-protect
	  (/ 1 0)
	(kill-buffer buffer)))))

and you will get what you expected without any user intervention.

> 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
> update...

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?



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: unwind-protect not cleaning up?
  2012-06-30  6:09     ` Eli Zaretskii
@ 2012-07-01 17:47       ` Jambunathan K
  2012-07-01 18:01         ` Jambunathan K
  0 siblings, 1 reply; 6+ messages in thread
From: Jambunathan K @ 2012-07-01 17:47 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: ofv, emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Jambunathan K <kjambunathan@gmail.com>
>> Date: Sat, 30 Jun 2012 11:01:21 +0530
>> Cc: emacs-devel@gnu.org
>> 
>> 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))
>       (unwind-protect
> 	  (/ 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
documented.

>> 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
>> update...
>
> 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*")))
  (with-current-buffer buffer
    (unwind-protect
	(while t (ignore)) ;; hog the cpu
      (kill-buffer buffer))))

If `debug-on-quit' is nil, then on C-g cleanup forms are executed.

[ADDITIONAL NOTE]
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.)


[CONTEXT SWITCH]
I also tried comparing `condition-case' with `unwind-protect'.

     (condition-case err
	 (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)

-- 



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: unwind-protect not cleaning up?
  2012-07-01 17:47       ` Jambunathan K
@ 2012-07-01 18:01         ` Jambunathan K
  0 siblings, 0 replies; 6+ messages in thread
From: Jambunathan K @ 2012-07-01 18:01 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: ofv, emacs-devel


> [CONTEXT SWITCH]
> I also tried comparing `condition-case' with `unwind-protect'.
>
>      (condition-case err
> 	 (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)

This paragraph is not clear even to me (the original author).  Let me
gather myself and articulate what I am trying to accomplish separately.

-- 



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-07-01 18:01 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-30  0:54 unwind-protect not cleaning up? Jambunathan K
2012-06-30  2:07 ` Óscar Fuentes
2012-06-30  5:31   ` Jambunathan K
2012-06-30  6:09     ` Eli Zaretskii
2012-07-01 17:47       ` Jambunathan K
2012-07-01 18:01         ` Jambunathan K

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).