On Tue, Dec 12, 2023 at 08:30:02PM -0500, Thomas Dickey wrote:
> On Wed, Dec 13, 2023 at 01:33:59AM +0100, наб wrote:
> > On Tue, Dec 12, 2023 at 05:55:38PM -0500, Thomas Dickey wrote:
> > > On Tue, Dec 12, 2023 at 11:09:13PM +0100, наб wrote:
> > > > urlview 1c-1 whose xterm was killed but which didn't die consumes 100% 
> > > > CPU.
> > > > The event loop is for(;;) switch(getch()) ... and ignores -1
> > > If it's going to ignore the error return (while at the same time
> > > manipulating the time delays with mousemask), then this is expected
> > > (mis)behavior.
> > Sure.
> > 
> > Still, it doesn't set errno to EINTR,
> ...and the manual page does not say it would do that.
> 
> It lists three possible causes for ERR being returned,
> and on the third it mentions that errno will be set:
>        returns ERR if the window pointer is null, or if its timeout
>        expires without having any data, or if the execution was interrupted by
>        a signal (errno will be set to EINTR).
> 
> It could be reformatted like this without changing its meaning:
>        returns ERR
>        * if the window pointer is null, or
>        * if its timeout expires without having any data, or
>        * if the execution was interrupted by a signal (errno will be set to
>          EINTR).
That, to me, wasn't clear from the page itself.
"any data (errno unchanged)" would make it so.

> > and instant empty reads you get from a hung-up teletype
> > definitely aren't exceeding the timeout.
> 
> https://git.sr.ht/~nabijaczleweli/urlview-ng/tree/1c/item/urlview.c#L441
> 
> mouseinterval(0) tells it to not wait for mouse events,
Well, mouseinterval(3curses) says
  Use mouseinterval(0) to disable click resolution.
which is different from "not wait for mouse events".

> That looks like someone's attempting to make the wheel mouse work at
> infinite velocity
The mouse wheel is checked-for with BUTTON[45]_PRESSED,
so click resolution doesn't factor in here at all.

I picked mouseinterval(0) because the default 166 value is completely
unusable. Clearly it doesn't actually disable click resolution either.

htop uses mouseinterval(0) as well.

Regardless of the mouseinterval argument I can click-hold-release
for however long I want, so long as I don't move the cursor too
much and it registers.
With the default value it just sleeps after I release.

In addition to my usual X teletype (st(1)),
this also happens with xterm(1) under both X configs I have,
so with it being under the dickey umbrella as well,
that clearly indicates that something's wrong to me.

This is also the case under gpm, on a 2002 Celeron laptop.
(And under X on that one as well.)

> I'd have used a 5msec delay (or 1msec for "modern" computers :-)
So is this a UI design choice or is it a VT-compat choice?
What's the point of this function, why does it not just correctly
associate clicks with clicks? Or, rather, why do you need mouseinterval(0)
to correctly associate clicks with clicks,
without "clearly broken" levels of delay?

Why do you suggest any delay at all?
Why 5ms or 1ms?
When is this (supposedly) needed?
What does computer recency have to do with it,
and why is that notion dispelled on the oldest piece of shit I have?
Why is none of this documented?

> -- and might be the reason for ignoring errors --
Mouse support is new, errors are ignored in 0.7 from 1997, so no.

> and might be the reason for the 100% CPU.
This all also happens with mouse and keypad disabled altogether,
so this is all moot.

> If ncurses is actually reading from a closed file descriptor, the manpage
> for read(2) suggests that errno may be set to EBADF
..? It isn't, and I never said it did. It reads from a valid fd,
which corresponds to a hanged-up tty. This is a consistent thoroughline.

> -- but since you say
> errno is _not_ being set, then there's nothing to alert ncurses to the
> problem -- the timeout expired.
There is no time-out:
> (You may get more insight using strace).
The straces you got both indicate that ncurses' first (only) read returns
empty, and any time-out isn't even attempted. You can tell because they
both say read(0, "", 1) = 0 exclusively, and neither of them have a poll.

Indeed, the only time the mouse timeout is attempted is /after/ a
mouse button down/up is read. There is another 1s poll timeout,
which happens after reading an ESC. Again, neither of those are attempted.

Similarly, they all end up in fifo_push() with
  340          n = (int) read(sp->_ifd, &c2, (size_t) 1);
  ...
  347      if ((n == -1) || (n == 0)) {
  348          TR(TRACE_IEVENT, ("read(%d,&ch,1)=%d, errno=%d", sp->_ifd, n, 
errno));
  349          ch = ERR;
  350      }
from (in the no-timeout case) _nc_wgetch() 
  596      } else {
  597          if (head == -1)
  598              fifo_push(sp EVENTLIST_2nd(evl));
  599          ch = fifo_pull(sp);
  600      }
  601
  602      if (ch == ERR) {
  ...
  620          returnCode(ERR);
again, no sleeps or timeouts or delays or intervals in this.

Consulting with the illumos-gate curses (usr/src/lib/libcurses/screen/tgetch.c),
it looks like it does the same thing,
and also doesn't document it, so presumably
  switch(errno = 0, getch()) {
  case ERR:
    if(errno == EINTR)
      continue;
    else if(errno)
      err(1, "getch()");
    else
      done = true;
    break;
  }
is fine.

Attachment: signature.asc
Description: PGP signature

Reply via email to