unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
       [not found] <E1CXPu6-00065f-6c@lists.gnu.org>
@ 2004-11-27  6:55 ` Richard Stallman
  2004-11-27 21:09   ` Stefan Monnier
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Stallman @ 2004-11-27  6:55 UTC (permalink / raw)
  Cc: emacs-devel

I haven't been following the thread, but it seems to have led
to a change in sysdep.c that seems unfortunate.

Until now, there has been no quitting inside writing a file,
which means that the file can't end up truncated as a result
of quitting.

What was the reason for this change?  What problem is it meant to solve?

***************
*** 3279,3285 ****
        if (rtnval == -1)
  	{
  	  if (errno == EINTR)
! 	    continue;
  	  else
  	    return (bytes_written ? bytes_written : -1);
  	}
--- 3285,3291 ----
        if (rtnval == -1)
  	{
  	  if (errno == EINTR)
! 	    { QUIT; continue; }
  	  else
  	    return (bytes_written ? bytes_written : -1);
  	}

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-11-27  6:55 ` [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c Richard Stallman
@ 2004-11-27 21:09   ` Stefan Monnier
  2004-11-29  6:11     ` Richard Stallman
  0 siblings, 1 reply; 14+ messages in thread
From: Stefan Monnier @ 2004-11-27 21:09 UTC (permalink / raw)
  Cc: emacs-devel

> I haven't been following the thread, but it seems to have led
> to a change in sysdep.c that seems unfortunate.

> Until now, there has been no quitting inside writing a file,
> which means that the file can't end up truncated as a result
> of quitting.

Hmm... what happens if you hit C-g while writing a file?
How does Emacs prevent truncation in the normal code?
Does it bind inhibit-quit (in which case it should work just fine with the
new code as well)?

> What was the reason for this change?  What problem is it meant to solve?

Being able to interrupt a write if it's blocking for a long time (like
write to an NFS server that's down).


        Stefan

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-11-27 21:09   ` Stefan Monnier
@ 2004-11-29  6:11     ` Richard Stallman
  2004-11-29 14:31       ` Stefan Monnier
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Stallman @ 2004-11-29  6:11 UTC (permalink / raw)
  Cc: emacs-devel

    Hmm... what happens if you hit C-g while writing a file?

Before your change, nothing, I believe.  That code was not
interruptible with quit.  It would write all the data, and the quit
would occur afterward.  Emacs might get confused as a result of
quitting inside the middle of the Lisp code to save the buffer, but
at least the file contents would not be truncated

    How does Emacs prevent truncation in the normal code?

I am not sure which code "the normal code" refers to,
but the way this code was written before, there was no QUIT check
during the actual writing of the data into the file.
So QUIT could never cause truncation.

    Being able to interrupt a write if it's blocking for a long time (like
    write to an NFS server that's down).

That is indeed desirable, so I think we have a problem of choosing
between two kinds of lossage.  I wish I could remember more clearly
what sort of problems could occur if quitting could truncate a file.

Maybe we could get the best of both worlds if we set it up so that
quit can occur inside emacs_write only if it has been sitting there
for 30 seconds or more since the last data it succeeded in writing.
That way, users could quit in the case of the dead NFS server,
but in all ordinary cases the quit would still be delayed until
after Fwrite_file has finished.

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-11-29  6:11     ` Richard Stallman
@ 2004-11-29 14:31       ` Stefan Monnier
  2004-11-30  7:03         ` Richard Stallman
  0 siblings, 1 reply; 14+ messages in thread
From: Stefan Monnier @ 2004-11-29 14:31 UTC (permalink / raw)
  Cc: emacs-devel

>     Hmm... what happens if you hit C-g while writing a file?
> Before your change, nothing, I believe.

Clearly, that's not the case.  C-g during the `write' (or at any other time
for that matter) would cause a signal-handler to be called that processed
the input.  This might either do a longjmp or just set quit-flag.

> That code was not interruptible with quit.  It would write all the data,
> and the quit would occur afterward.  Emacs might get confused as a result
> of quitting inside the middle of the Lisp code to save the buffer, but at
> least the file contents would not be truncated

BTW, is a 2MB file is currently written with a single call to `write'?

>     How does Emacs prevent truncation in the normal code?

> I am not sure which code "the normal code" refers to,
> but the way this code was written before, there was no QUIT check
> during the actual writing of the data into the file.
> So QUIT could never cause truncation.

So you're saying that the signal handler just sets quit-flag rather than
calling longjmp.  Hmmm.... I guess that makes sense.

>     Being able to interrupt a write if it's blocking for a long time (like
>     write to an NFS server that's down).

> That is indeed desirable, so I think we have a problem of choosing
> between two kinds of lossage.

Well, we can at least revert to the previous behavior while still make
SYNC_INPUT behave somewhat like non-SYNC_INPUT by replacing QUIT with:

    if (interrupt_input_pending)
      handle_async_input ();

which is the part of QUIT I actually need there.

> I wish I could remember more clearly what sort of problems could occur if
> quitting could truncate a file.

It's pretty obvious: you end up with a broken file.  Maybe there's some
other effect, but that one is bad enough already.

> Maybe we could get the best of both worlds if we set it up so that
> quit can occur inside emacs_write only if it has been sitting there
> for 30 seconds or more since the last data it succeeded in writing.
> That way, users could quit in the case of the dead NFS server,
> but in all ordinary cases the quit would still be delayed until
> after Fwrite_file has finished.

I always felt like there should be a way to force an immediate_quit, not
only is `write'.  Maybe by hitting C-g three times in a row or something
like that.  Or maybe if you haven't hit anything else than C-g in the last
N seconds and the first C-g is still not processed.


        Stefan

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-11-29 14:31       ` Stefan Monnier
@ 2004-11-30  7:03         ` Richard Stallman
  2004-11-30 13:08           ` Stefan
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Stallman @ 2004-11-30  7:03 UTC (permalink / raw)
  Cc: emacs-devel

    >     Hmm... what happens if you hit C-g while writing a file?
    > Before your change, nothing, I believe.

    Clearly, that's not the case.  C-g during the `write' (or at any other time
    for that matter) would cause a signal-handler to be called that processed
    the input.  This might either do a longjmp or just set quit-flag.

The signal handler would indeed run and set quit-flag, and return, but
the net effect on the code that writes the file was nil.

    BTW, is a 2MB file is currently written with a single call to `write'?

Sometimes it can be, I think; however, in general Fwrite_file can call
`write' many times.  However, there was no use of QUIT in and among
them.

    I always felt like there should be a way to force an immediate_quit, not
    only is `write'.  Maybe by hitting C-g three times in a row or something
    like that.

Hitting C-g twice activates the emergency escape, which is even more
drastic than that.  However, this feature is only active on ttys.


So what do you think of the following idea?

    > Maybe we could get the best of both worlds if we set it up so that
    > quit can occur inside emacs_write only if it has been sitting there
    > for 30 seconds or more since the last data it succeeded in writing.

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-11-30  7:03         ` Richard Stallman
@ 2004-11-30 13:08           ` Stefan
  2004-12-01  2:57             ` Richard Stallman
  0 siblings, 1 reply; 14+ messages in thread
From: Stefan @ 2004-11-30 13:08 UTC (permalink / raw)
  Cc: emacs-devel

>     BTW, is a 2MB file is currently written with a single call to `write'?

> Sometimes it can be, I think; however, in general Fwrite_file can call
> `write' many times.  However, there was no use of QUIT in and among
> them.

I see, thanks.

>     I always felt like there should be a way to force an immediate_quit, not
>     only is `write'.  Maybe by hitting C-g three times in a row or something
>     like that.

> Hitting C-g twice activates the emergency escape, which is even more
> drastic than that.  However, this feature is only active on ttys.

I think what I want is exactly this emergency feature.  I.e. it should be
active not only in ttys.  (and it should ignore inhibit-quit, although
I expect it already does).  (tho, maybe doing it for just a "double C-g" is
excessive, I think it should require a more unusual trigger).

> So what do you think of the following idea?

>> Maybe we could get the best of both worlds if we set it up so that
>> quit can occur inside emacs_write only if it has been sitting there
>> for 30 seconds or more since the last data it succeeded in writing.

The idea sounds good, assuming you don't mean it to be specific to `write'.


        Stefan

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-11-30 13:08           ` Stefan
@ 2004-12-01  2:57             ` Richard Stallman
  2004-12-01  4:28               ` Stefan
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Stallman @ 2004-12-01  2:57 UTC (permalink / raw)
  Cc: emacs-devel

The basic idea of the "emergency escape" feature is to provide a way
to get out of Emacs when it is not responding at all.

This is not needed on a window system, because you can make yourself
an xterm or whatever even if Emacs is not listening to you.  And you
could use the xterm to kill Emacs if that is what you want to do.

What did you wish to do using emergency escape under a window system?

    >> Maybe we could get the best of both worlds if we set it up so that
    >> quit can occur inside emacs_write only if it has been sitting there
    >> for 30 seconds or more since the last data it succeeded in writing.

    The idea sounds good, assuming you don't mean it to be specific to `write'.

The idea I had in mind is specific to e_write.  It is not needed for anything
else.  Most parts of Emacs will quit *very soon* if you type C-g.

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-12-01  2:57             ` Richard Stallman
@ 2004-12-01  4:28               ` Stefan
  2004-12-01  9:37                 ` Andreas Schwab
                                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Stefan @ 2004-12-01  4:28 UTC (permalink / raw)
  Cc: emacs-devel

> What did you wish to do using emergency escape under a window system?

Get out of a infinite elisp loop executed while inhibit-quit is non-nil
(e.g. an infinite loop in a post-command-hook or a timer).
Yes, I can kill the Emacs process, but it's a real pity to have to do that
when there's nothing really wrong with it.
Of course, all those cases are bugs we should fix, but they do happen,
sometimes while writing/testing/debugging code.

> Most parts of Emacs will quit *very soon* if you type C-g.

Yes, for those C-g is all we need.  But there are others, like `write'.


        Stefan

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-12-01  4:28               ` Stefan
@ 2004-12-01  9:37                 ` Andreas Schwab
  2004-12-01 18:21                 ` Eli Zaretskii
                                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Andreas Schwab @ 2004-12-01  9:37 UTC (permalink / raw)
  Cc: rms, emacs-devel

Stefan <monnier@iro.umontreal.ca> writes:

>> What did you wish to do using emergency escape under a window system?
>
> Get out of a infinite elisp loop executed while inhibit-quit is non-nil
> (e.g. an infinite loop in a post-command-hook or a timer).
> Yes, I can kill the Emacs process, but it's a real pity to have to do that
> when there's nothing really wrong with it.
> Of course, all those cases are bugs we should fix, but they do happen,
> sometimes while writing/testing/debugging code.

You can also attach a debugger and set inhibit-quit to nil.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-12-01  4:28               ` Stefan
  2004-12-01  9:37                 ` Andreas Schwab
@ 2004-12-01 18:21                 ` Eli Zaretskii
  2004-12-02 13:10                 ` Richard Stallman
  2004-12-05 20:23                 ` Juri Linkov
  3 siblings, 0 replies; 14+ messages in thread
From: Eli Zaretskii @ 2004-12-01 18:21 UTC (permalink / raw)
  Cc: emacs-devel

> From: Stefan <monnier@iro.umontreal.ca>
> Date: Tue, 30 Nov 2004 23:28:33 -0500
> Cc: emacs-devel@gnu.org
> 
> > What did you wish to do using emergency escape under a window system?
> 
> Get out of a infinite elisp loop executed while inhibit-quit is non-nil
> (e.g. an infinite loop in a post-command-hook or a timer).
> Yes, I can kill the Emacs process, but it's a real pity to have to do that
> when there's nothing really wrong with it.

IIRC, emergency escape won't help you do anything except the
equivalent of killing Emacs with a fatal signal.

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-12-01  4:28               ` Stefan
  2004-12-01  9:37                 ` Andreas Schwab
  2004-12-01 18:21                 ` Eli Zaretskii
@ 2004-12-02 13:10                 ` Richard Stallman
  2004-12-05 20:23                 ` Juri Linkov
  3 siblings, 0 replies; 14+ messages in thread
From: Richard Stallman @ 2004-12-02 13:10 UTC (permalink / raw)
  Cc: emacs-devel

    > Most parts of Emacs will quit *very soon* if you type C-g.

    Yes, for those C-g is all we need.  But there are others, like `write'.

For `write', and maybe other exceptional places where at present C-g
won't ever exit the loop, I suggested that we make a single C-g exit,
but only if there has been no progress in the loop for 30 seconds.

Wouldn't that solve the problem?

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-12-01  4:28               ` Stefan
                                   ` (2 preceding siblings ...)
  2004-12-02 13:10                 ` Richard Stallman
@ 2004-12-05 20:23                 ` Juri Linkov
  2004-12-05 22:33                   ` Stefan Monnier
  2004-12-06  1:40                   ` Richard Stallman
  3 siblings, 2 replies; 14+ messages in thread
From: Juri Linkov @ 2004-12-05 20:23 UTC (permalink / raw)
  Cc: rms, emacs-devel

Stefan <monnier@iro.umontreal.ca> writes:
>> What did you wish to do using emergency escape under a window system?
>
> Get out of a infinite elisp loop executed while inhibit-quit is non-nil
> (e.g. an infinite loop in a post-command-hook or a timer).

I don't quite understand why it is assumed that everything run by
a post-command-hook or a timer is a critical code not allowed to be
interrupted with C-g?  One of the timers where such assumption has
a negative effect is the isearch lazy highlighting timer which often
enters into a very deep loop (several minutes and more) trying to
fontify regexps with nested repetition constructs, and which is not
interruptible with C-g.

Surely, it is possible to enclose the whole `isearch-lazy-highlight-update'
function in `with-local-quit' block, if the assumption that timers should
be non-interruptible by default is somehow justified.

> Yes, I can kill the Emacs process, but it's a real pity to have to do that
> when there's nothing really wrong with it.
> Of course, all those cases are bugs we should fix, but they do happen,
> sometimes while writing/testing/debugging code.

Is it a bug that regex.c can't detect long or infinite loops?

-- 
Juri Linkov
http://www.jurta.org/emacs/

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-12-05 20:23                 ` Juri Linkov
@ 2004-12-05 22:33                   ` Stefan Monnier
  2004-12-06  1:40                   ` Richard Stallman
  1 sibling, 0 replies; 14+ messages in thread
From: Stefan Monnier @ 2004-12-05 22:33 UTC (permalink / raw)
  Cc: rms, emacs-devel

>>> What did you wish to do using emergency escape under a window system?
>> Get out of a infinite elisp loop executed while inhibit-quit is non-nil
>> (e.g. an infinite loop in a post-command-hook or a timer).

> I don't quite understand why it is assumed that everything run by
> a post-command-hook or a timer is a critical code not allowed to be
> interrupted with C-g?

The way existing code is written, allowing quit could lead to corrupted
states, so we can't just change it.  Furthermore, the problem of
uninterruptible code is not limited to post-command-hook and timers.
So I'd rather have a general solution: a form of C-g that tries really hard
to interrupt the current code, even if it risks putting the process in
a somewhat corrupted state.

>> Yes, I can kill the Emacs process, but it's a real pity to have to do
>> that when there's nothing really wrong with it.  Of course, all those
>> cases are bugs we should fix, but they do happen, sometimes while
>> writing/testing/debugging code.

> Is it a bug that regex.c can't detect long or infinite loops?

It can probably be considered as a performance bug (the complexity of regexp
matching should be O(n*m) where `n' and `m' are the size of the text and of
the regexp), but since we're not going to switch over to a different
algorithm any time soon (especially seeing as we're forking further away
from a clean non-Emacs-specific regexp.c), we just have to live with it.

As for "detection", it's basically impossible, no.
OTOH it shouldn't be too hard to obey C-g.


        Stefan

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

* Re: [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c
  2004-12-05 20:23                 ` Juri Linkov
  2004-12-05 22:33                   ` Stefan Monnier
@ 2004-12-06  1:40                   ` Richard Stallman
  1 sibling, 0 replies; 14+ messages in thread
From: Richard Stallman @ 2004-12-06  1:40 UTC (permalink / raw)
  Cc: monnier, emacs-devel

    I don't quite understand why it is assumed that everything run by
    a post-command-hook or a timer is a critical code not allowed to be
    interrupted with C-g?

When code runs asynchronously, the user could interrupt it without
knowing he's interrupting anything.  That gives a lot of potential
for confusion.

      One of the timers where such assumption has
    a negative effect is the isearch lazy highlighting timer which often
    enters into a very deep loop (several minutes and more) trying to
    fontify regexps with nested repetition constructs, and which is not
    interruptible with C-g.

If that loop has the potential to run along time, it should check for
arrival of input, and stop when input arrives.

We were just recently talking about how to implement a construct to
interrupt some code if input arrives.  I suggested code to implement
it; then someone reported a problem in it, but I think I found a fix
for that.  Would use of that code solve this problem?

    Is it a bug that regex.c can't detect long or infinite loops?

It would be nice if it could do so, but I hesitate to say this is a
bug, because that might be tantamount to demanding the impossible.

However, maybe it isn't impossible.  Do you think it is doable?  Would
you like to try?

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

end of thread, other threads:[~2004-12-06  1:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <E1CXPu6-00065f-6c@lists.gnu.org>
2004-11-27  6:55 ` [Emacs-trunk-diffs] Changes to emacs/src/sysdep.c Richard Stallman
2004-11-27 21:09   ` Stefan Monnier
2004-11-29  6:11     ` Richard Stallman
2004-11-29 14:31       ` Stefan Monnier
2004-11-30  7:03         ` Richard Stallman
2004-11-30 13:08           ` Stefan
2004-12-01  2:57             ` Richard Stallman
2004-12-01  4:28               ` Stefan
2004-12-01  9:37                 ` Andreas Schwab
2004-12-01 18:21                 ` Eli Zaretskii
2004-12-02 13:10                 ` Richard Stallman
2004-12-05 20:23                 ` Juri Linkov
2004-12-05 22:33                   ` Stefan Monnier
2004-12-06  1:40                   ` Richard Stallman

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