all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* unwind-protect and inhibit-quit
@ 2021-07-15 15:14 Felix Dietrich
  2021-07-16  7:18 ` Eli Zaretskii
  0 siblings, 1 reply; 15+ messages in thread
From: Felix Dietrich @ 2021-07-15 15:14 UTC (permalink / raw)
  To: help-gnu-emacs

Hello,

I have questions regarding “unwind-protect” and the two examples
provided in the elisp reference manual [1].


    ;; 1. Example
    (let ((buffer (get-buffer-create " *temp*")))
      (with-current-buffer buffer
        (unwind-protect
            body-form
          (kill-buffer buffer))))


    ;; 2. Example
    (let ((win nil))
      (unwind-protect
          (progn
            (setq process (ftp-setup-buffer host file))
            (if (setq win (ftp-login process host user password))
                (message "Logged in")
              (error "Ftp login failed")))
        (or win (and process (delete-process process)))))


In the last paragraph [2], the description of the second example mentions a
race condition between the assignment of the “ftp-setup-buffer”
functionʼs return value to the variable “process” and the user sending a
quit signal (C-g).  Does the first example suffer from the same issue in
itʼs assignment to the “buffer” variable?

That paragraph also mentions that “there is no easy way to fix this
bug”.  Is that statement still true or can this issue be resolved by
setting “inhibit-quit” in current Emacs versions:


    ;; 2. Example (added inhibit-quit)
    (let ((win nil))
      (unwind-protect
          (progn
            (let ((inhibit-quit t))
              (setq process (ftp-setup-buffer host file)))
            (if (setq win (ftp-login process host user password))
                (message "Logged in")
              (error "Ftp login failed")))
        (or win (and process (delete-process process)))))


The first example has the “unwind-protect” form nested inside
“with-current-buffer”; this leaves a window where the buffer is both
created and assigned to the variable “buffer” but not protected from
being left alive in case of a quit (or, in more elaborated uses, an
error).  Shouldn’t it, therefore, be the other way around:
“unwind-protect” wrapping “with-current-buffer”?  In the following
snippet I also have added “inhibit-quit”, assuming that it works like I
expect.


    ;; 1. Example (moved unwind-protect up; added inhibit-quit)
    (let (buffer)
      (unwind-protect
          (progn
            (let ((inhibit-quit t))
              (setq buffer (get-buffer-create " *temp*")))
            (with-current-buffer buffer
              body-form))
        (and buffer (kill-buffer buffer))))


There also seems to be an issue in the first example with modifying and
killing a potentially already existing buffer " *temp*", which could be
avoided, I believe, by using “generate-new-buffer”:


    ;; 1. Example (moved unwind-protect up; added inhibit-quit;
    ;;             use generate-new-buffer)
    (let (buffer)
      (unwind-protect
          (progn
            (let ((inhibit-quit t))
              (setq buffer (generate-new-buffer " *temp*")))
            (with-current-buffer buffer
              body-form))
        (and buffer (kill-buffer buffer))))


Does “generate-new-buffer” make the same guarantee as
“get-buffer-create” that it will never return nil?  At least
“generate-new-buffer” is implemented with “get-buffer-create”.


Footnotes:
[1]  <https://www.gnu.org/software/emacs/manual/html_node/elisp/Cleanups.html>
     
     (info "(elisp) Cleanups")

[2]  “This example has a small bug: if the user types C-g to quit, and the
     quit happens immediately after the function ftp-setup-buffer
     returns but before the variable process is set, the process will
     not be killed. There is no easy way to fix this bug, but at least
     it is very unlikely.”

-- 
Felix Dietrich



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

end of thread, other threads:[~2021-07-17 16:34 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-07-15 15:14 unwind-protect and inhibit-quit Felix Dietrich
2021-07-16  7:18 ` Eli Zaretskii
2021-07-16  8:10   ` Thibaut Verron
2021-07-16 11:19     ` Eli Zaretskii
2021-07-16 14:46       ` Felix Dietrich
2021-07-16 14:56         ` Felix Dietrich
2021-07-16 15:00     ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-07-16 20:01       ` Thibaut Verron
2021-07-16 20:06         ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-07-16 21:30       ` Felix Dietrich
2021-07-16 21:37         ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-07-17 11:52           ` Felix Dietrich
2021-07-17  6:20         ` Eli Zaretskii
2021-07-17 15:46           ` Felix Dietrich
2021-07-17 16:34             ` Eli Zaretskii

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.