Re: Another pipe-related problem?

2021-11-09 Thread Backwoods BC via Cygwin
Please pardon the interjection. I'm a hardware guy and any time a
hardware process is in a state where it is waiting for a signal from
another process, I put in a timeout mechanism. Shouldn't this be a
normal practice for software as well?

-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Ken Brown via Cygwin

On 11/9/2021 5:20 PM, Ken Brown via Cygwin wrote:

On 11/9/2021 5:16 PM, Ken Brown via Cygwin wrote:

On 11/9/2021 9:11 AM, Ken Brown via Cygwin wrote:

On 11/9/2021 5:55 AM, Henry S. Thompson wrote:

As you may know, the XEmacs situation is complicated.  The old source
repo (bitbucket.org/xemacs) no longer exists.  There's a fork that's
still being maintained, but it's not widely publicised.  That's the
one I'm working with -- are you aware of this.


I was aware that the bitbucket repo didn't exist, because I tried to get the 
sources there.  But I didn't know about the fork.  Please point me to it, or 
just make a tarball available to me somehow.



Here are the immediate contexts from the sources for the xemacs
sources in the above backtrace, might be enough to check your
hypothesis:

sysdep.c:

   retry_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
   {
 ssize_t rtnval;

 while ((rtnval = read (fildes, buf, nbyte)) == -1
    && (errno == EINTR)) 
   {
 if (allow_quit)
   QUIT;
   }
 return rtnval;
   }
I'll have to reproduce the hang myself in order to test this (or maybe you 
could test it), but I now have a new guess: If the read call above keeps 
failing with EINTR, then we're in an infinite loop.  This could happen 
because of the following code in fhandler_pipe::raw_read:


   DWORD waitret = cygwait (read_mtx, timeout);
   switch (waitret)
 {
 case WAIT_OBJECT_0:
   break;
 case WAIT_TIMEOUT:
   set_errno (EAGAIN);
   len = (size_t) -1;
   return;
 default:
   set_errno (EINTR);
   len = (size_t) -1;
   return;
 }

Takashi, is EINTR really the appropriate errno in the default case?  Isn't 
cygwait supposed to handle signals?


I was able to build XEmacs and reproduce the problem.  My guess was wrong, 
though my question to Takashi still stands.  I think the infinite loop is 
actually caused by a bug in fhandler_pipe::raw_read that only affects 
non-blocking pipes (which is what we have in XEmacs).


Consider the following code in fhandler_pipe::raw_read:

   status = NtReadFile (get_handle (), evt, NULL, NULL, &io, ptr,
    len1, NULL, NULL);
   if (evt && status == STATUS_PENDING)  
 {
   waitret = cygwait (evt, INFINITE, cw_cancel | cw_sig);
[...]
 }

In the non-blocking case, evt == NULL, but we still might have status == 
STATUS_PENDING.  We then should wait on get_handle() to let NtReadFile finish. 
By not waiting, we end up using a garbage value from io.Information, leading 
to an infinite loop in drain_signal_event_pipe.


Nope, that doesn't seem to be the issue.  Even after fixing this, I still see an 
infinite loop.  Probably NtReadFile finishes quickly enough that io.Information 
is in fact valid by the time we test it.  Back to the drawing board.


BTW, a quick glance at raw_write suggests that there might be a similar bug 
there, but I'll have to look more closely.


Ken


--
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Ken Brown via Cygwin

On 11/9/2021 7:37 PM, Takashi Yano via Cygwin wrote:

On Wed, 10 Nov 2021 09:16:13 +0900
Takashi Yano wrote:

On Wed, 10 Nov 2021 08:48:22 +0900
Takashi Yano wrote:

On Wed, 10 Nov 2021 08:29:32 +0900
Takashi Yano wrote:

On Wed, 10 Nov 2021 08:22:45 +0900
Takashi Yano wrote:

On Tue, 9 Nov 2021 09:11:28 -0500
Ken Brown wrote:

I'll have to reproduce the hang myself in order to test this (or maybe you could
test it), but I now have a new guess: If the read call above keeps failing with
EINTR, then we're in an infinite loop.  This could happen because of the
following code in fhandler_pipe::raw_read:

DWORD waitret = cygwait (read_mtx, timeout);
switch (waitret)
  {
  case WAIT_OBJECT_0:
break;
  case WAIT_TIMEOUT:
set_errno (EAGAIN);
len = (size_t) -1;
return;
  default:
set_errno (EINTR);
len = (size_t) -1;
return;
  }

Takashi, is EINTR really the appropriate errno in the default case?  Isn't
cygwait supposed to handle signals?


I assume cygwait() returns WAIT_SIGNALED when signalled
by SIGINT, SIGTERM, SIGTSTP, etc...  In this case, EINTR
should return I think.

Is it wrong?


Ah, if SA_RESTART is set, we should continue to read even
if signalled...

[...]

No, we don't have to do that because cygwait() do the same
internally. cygwain() returns WAIT_SIGNALED when signalled
only if SA_RESTART is not set. So, the current code LGTM.


Ah, however, should we handle WAIT_CANCELED here and call
pthread::static_cancel_self() as following?

DWORD waitret = cygwait (read_mtx, timeout);
switch (waitret)
  {
  case WAIT_OBJECT_0:
break;
  case WAIT_TIMEOUT:
set_errno (EAGAIN);
len = (size_t) -1;
return;
  WAIT_SIGNALED:
set_errno (EINTR);
len = (size_t) -1;
return;
  WAIT_CANCELED:
pthread::static_cancel_self ();
/* NOTREACHED */
  default:
/* Should not reach here. */
__seterrno ();
len = (slze_t) -1;
return;
  }


This looks better to me.  I think the default case actually could be reached if 
WFMO returns WAIT_FAILED (admittedly unlikely).


Ken

--
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Takashi Yano via Cygwin
On Wed, 10 Nov 2021 09:16:13 +0900
Takashi Yano wrote:
> On Wed, 10 Nov 2021 08:48:22 +0900
> Takashi Yano wrote:
> > On Wed, 10 Nov 2021 08:29:32 +0900
> > Takashi Yano wrote:
> > > On Wed, 10 Nov 2021 08:22:45 +0900
> > > Takashi Yano wrote:
> > > > On Tue, 9 Nov 2021 09:11:28 -0500
> > > > Ken Brown wrote:
> > > > > I'll have to reproduce the hang myself in order to test this (or 
> > > > > maybe you could 
> > > > > test it), but I now have a new guess: If the read call above keeps 
> > > > > failing with 
> > > > > EINTR, then we're in an infinite loop.  This could happen because of 
> > > > > the 
> > > > > following code in fhandler_pipe::raw_read:
> > > > > 
> > > > >DWORD waitret = cygwait (read_mtx, timeout);
> > > > >switch (waitret)
> > > > >  {
> > > > >  case WAIT_OBJECT_0:
> > > > >break;
> > > > >  case WAIT_TIMEOUT:
> > > > >set_errno (EAGAIN);
> > > > >len = (size_t) -1;
> > > > >return;
> > > > >  default:
> > > > >set_errno (EINTR);
> > > > >len = (size_t) -1;
> > > > >return;
> > > > >  }
> > > > > 
> > > > > Takashi, is EINTR really the appropriate errno in the default case?  
> > > > > Isn't 
> > > > > cygwait supposed to handle signals?
> > > > 
> > > > I assume cygwait() returns WAIT_SIGNALED when signalled
> > > > by SIGINT, SIGTERM, SIGTSTP, etc...  In this case, EINTR
> > > > should return I think.
> > > > 
> > > > Is it wrong?
> > > 
> > > Ah, if SA_RESTART is set, we should continue to read even
> > > if signalled...
[...]
> No, we don't have to do that because cygwait() do the same
> internally. cygwain() returns WAIT_SIGNALED when signalled
> only if SA_RESTART is not set. So, the current code LGTM.

Ah, however, should we handle WAIT_CANCELED here and call
pthread::static_cancel_self() as following?

   DWORD waitret = cygwait (read_mtx, timeout);
   switch (waitret)
 {
 case WAIT_OBJECT_0:
   break;
 case WAIT_TIMEOUT:
   set_errno (EAGAIN);
   len = (size_t) -1;
   return;
 WAIT_SIGNALED:
   set_errno (EINTR);
   len = (size_t) -1;
   return;
 WAIT_CANCELED:
   pthread::static_cancel_self ();
   /* NOTREACHED */
 default:
   /* Should not reach here. */
   __seterrno ();
   len = (slze_t) -1;
   return;
 }


-- 
Takashi Yano 

-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Takashi Yano via Cygwin
On Wed, 10 Nov 2021 08:48:22 +0900
Takashi Yano wrote:
> On Wed, 10 Nov 2021 08:29:32 +0900
> Takashi Yano wrote:
> > On Wed, 10 Nov 2021 08:22:45 +0900
> > Takashi Yano wrote:
> > > On Tue, 9 Nov 2021 09:11:28 -0500
> > > Ken Brown wrote:
> > > > I'll have to reproduce the hang myself in order to test this (or maybe 
> > > > you could 
> > > > test it), but I now have a new guess: If the read call above keeps 
> > > > failing with 
> > > > EINTR, then we're in an infinite loop.  This could happen because of 
> > > > the 
> > > > following code in fhandler_pipe::raw_read:
> > > > 
> > > >DWORD waitret = cygwait (read_mtx, timeout);
> > > >switch (waitret)
> > > >  {
> > > >  case WAIT_OBJECT_0:
> > > >break;
> > > >  case WAIT_TIMEOUT:
> > > >set_errno (EAGAIN);
> > > >len = (size_t) -1;
> > > >return;
> > > >  default:
> > > >set_errno (EINTR);
> > > >len = (size_t) -1;
> > > >return;
> > > >  }
> > > > 
> > > > Takashi, is EINTR really the appropriate errno in the default case?  
> > > > Isn't 
> > > > cygwait supposed to handle signals?
> > > 
> > > I assume cygwait() returns WAIT_SIGNALED when signalled
> > > by SIGINT, SIGTERM, SIGTSTP, etc...  In this case, EINTR
> > > should return I think.
> > > 
> > > Is it wrong?
> > 
> > Ah, if SA_RESTART is set, we should continue to read even
> > if signalled...
> 
> So, should this be like following?
> 
>  restart_wait_read_mtx:
>DWORD waitret = cygwait (read_mtx, timeout, cw_sig_eintr);
>switch (waitret)
>  {
>  case WAIT_OBJECT_0:
>break;
>  case WAIT_TIMEOUT:
>set_errno (EAGAIN);
>len = (size_t) -1;
>return;
>  case WAIT_SIGNALED:
>if (_my_tls.call_signal_handler ())
>  goto restart_wait_read_mtx;
>set_errno (EINTR);
>len = (size_t) -1;
>return;
>  default:
>/* Should not reach here. */
>__seterrno ();
>len = (size_t) -1;
>return;
>  }

No, we don't have to do that because cygwait() do the same
internally. cygwain() returns WAIT_SIGNALED when signalled
only if SA_RESTART is not set. So, the current code LGTM.

-- 
Takashi Yano 

-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Takashi Yano via Cygwin
On Wed, 10 Nov 2021 08:29:32 +0900
Takashi Yano wrote:
> On Wed, 10 Nov 2021 08:22:45 +0900
> Takashi Yano wrote:
> > On Tue, 9 Nov 2021 09:11:28 -0500
> > Ken Brown wrote:
> > > I'll have to reproduce the hang myself in order to test this (or maybe 
> > > you could 
> > > test it), but I now have a new guess: If the read call above keeps 
> > > failing with 
> > > EINTR, then we're in an infinite loop.  This could happen because of the 
> > > following code in fhandler_pipe::raw_read:
> > > 
> > >DWORD waitret = cygwait (read_mtx, timeout);
> > >switch (waitret)
> > >  {
> > >  case WAIT_OBJECT_0:
> > >break;
> > >  case WAIT_TIMEOUT:
> > >set_errno (EAGAIN);
> > >len = (size_t) -1;
> > >return;
> > >  default:
> > >set_errno (EINTR);
> > >len = (size_t) -1;
> > >return;
> > >  }
> > > 
> > > Takashi, is EINTR really the appropriate errno in the default case?  
> > > Isn't 
> > > cygwait supposed to handle signals?
> > 
> > I assume cygwait() returns WAIT_SIGNALED when signalled
> > by SIGINT, SIGTERM, SIGTSTP, etc...  In this case, EINTR
> > should return I think.
> > 
> > Is it wrong?
> 
> Ah, if SA_RESTART is set, we should continue to read even
> if signalled...

So, should this be like following?

 restart_wait_read_mtx:
   DWORD waitret = cygwait (read_mtx, timeout, cw_sig_eintr);
   switch (waitret)
 {
 case WAIT_OBJECT_0:
   break;
 case WAIT_TIMEOUT:
   set_errno (EAGAIN);
   len = (size_t) -1;
   return;
 case WAIT_SIGNALED:
   if (_my_tls.call_signal_handler ())
 goto restart_wait_read_mtx;
   set_errno (EINTR);
   len = (size_t) -1;
   return;
 default:
   /* Should not reach here. */
   __seterrno ();
   len = (size_t) -1;
   return;
 }

-- 
Takashi Yano 

-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Takashi Yano via Cygwin
On Wed, 10 Nov 2021 08:22:45 +0900
Takashi Yano wrote:
> On Tue, 9 Nov 2021 09:11:28 -0500
> Ken Brown wrote:
> > I'll have to reproduce the hang myself in order to test this (or maybe you 
> > could 
> > test it), but I now have a new guess: If the read call above keeps failing 
> > with 
> > EINTR, then we're in an infinite loop.  This could happen because of the 
> > following code in fhandler_pipe::raw_read:
> > 
> >DWORD waitret = cygwait (read_mtx, timeout);
> >switch (waitret)
> >  {
> >  case WAIT_OBJECT_0:
> >break;
> >  case WAIT_TIMEOUT:
> >set_errno (EAGAIN);
> >len = (size_t) -1;
> >return;
> >  default:
> >set_errno (EINTR);
> >len = (size_t) -1;
> >return;
> >  }
> > 
> > Takashi, is EINTR really the appropriate errno in the default case?  Isn't 
> > cygwait supposed to handle signals?
> 
> I assume cygwait() returns WAIT_SIGNALED when signalled
> by SIGINT, SIGTERM, SIGTSTP, etc...  In this case, EINTR
> should return I think.
> 
> Is it wrong?

Ah, if SA_RESTART is set, we should continue to read even
if signalled...

-- 
Takashi Yano 

-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Takashi Yano via Cygwin
On Tue, 9 Nov 2021 09:11:28 -0500
Ken Brown wrote:
> I'll have to reproduce the hang myself in order to test this (or maybe you 
> could 
> test it), but I now have a new guess: If the read call above keeps failing 
> with 
> EINTR, then we're in an infinite loop.  This could happen because of the 
> following code in fhandler_pipe::raw_read:
> 
>DWORD waitret = cygwait (read_mtx, timeout);
>switch (waitret)
>  {
>  case WAIT_OBJECT_0:
>break;
>  case WAIT_TIMEOUT:
>set_errno (EAGAIN);
>len = (size_t) -1;
>return;
>  default:
>set_errno (EINTR);
>len = (size_t) -1;
>return;
>  }
> 
> Takashi, is EINTR really the appropriate errno in the default case?  Isn't 
> cygwait supposed to handle signals?

I assume cygwait() returns WAIT_SIGNALED when signalled
by SIGINT, SIGTERM, SIGTSTP, etc...  In this case, EINTR
should return I think.

Is it wrong?

-- 
Takashi Yano 

-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Ken Brown via Cygwin

On 11/9/2021 5:16 PM, Ken Brown via Cygwin wrote:

On 11/9/2021 9:11 AM, Ken Brown via Cygwin wrote:

On 11/9/2021 5:55 AM, Henry S. Thompson wrote:

As you may know, the XEmacs situation is complicated.  The old source
repo (bitbucket.org/xemacs) no longer exists.  There's a fork that's
still being maintained, but it's not widely publicised.  That's the
one I'm working with -- are you aware of this.


I was aware that the bitbucket repo didn't exist, because I tried to get the 
sources there.  But I didn't know about the fork.  Please point me to it, or 
just make a tarball available to me somehow.



Here are the immediate contexts from the sources for the xemacs
sources in the above backtrace, might be enough to check your
hypothesis:

sysdep.c:

   retry_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
   {
 ssize_t rtnval;

 while ((rtnval = read (fildes, buf, nbyte)) == -1
    && (errno == EINTR)) 
   {
 if (allow_quit)
   QUIT;
   }
 return rtnval;
   }
I'll have to reproduce the hang myself in order to test this (or maybe you 
could test it), but I now have a new guess: If the read call above keeps 
failing with EINTR, then we're in an infinite loop.  This could happen because 
of the following code in fhandler_pipe::raw_read:


   DWORD waitret = cygwait (read_mtx, timeout);
   switch (waitret)
 {
 case WAIT_OBJECT_0:
   break;
 case WAIT_TIMEOUT:
   set_errno (EAGAIN);
   len = (size_t) -1;
   return;
 default:
   set_errno (EINTR);
   len = (size_t) -1;
   return;
 }

Takashi, is EINTR really the appropriate errno in the default case?  Isn't 
cygwait supposed to handle signals?


I was able to build XEmacs and reproduce the problem.  My guess was wrong, 
though my question to Takashi still stands.  I think the infinite loop is 
actually caused by a bug in fhandler_pipe::raw_read that only affects 
non-blocking pipes (which is what we have in XEmacs).


Consider the following code in fhandler_pipe::raw_read:

   status = NtReadFile (get_handle (), evt, NULL, NULL, &io, ptr,
    len1, NULL, NULL);
   if (evt && status == STATUS_PENDING)  
 {
   waitret = cygwait (evt, INFINITE, cw_cancel | cw_sig);
[...]
 }

In the non-blocking case, evt == NULL, but we still might have status == 
STATUS_PENDING.  We then should wait on get_handle() to let NtReadFile finish. 
By not waiting, we end up using a garbage value from io.Information, leading to 
an infinite loop in drain_signal_event_pipe.


I'll try to fix this.


BTW, a quick glance at raw_write suggests that there might be a similar bug 
there, but I'll have to look more closely.


Ken

--
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Ken Brown via Cygwin

On 11/9/2021 9:11 AM, Ken Brown via Cygwin wrote:

On 11/9/2021 5:55 AM, Henry S. Thompson wrote:

As you may know, the XEmacs situation is complicated.  The old source
repo (bitbucket.org/xemacs) no longer exists.  There's a fork that's
still being maintained, but it's not widely publicised.  That's the
one I'm working with -- are you aware of this.


I was aware that the bitbucket repo didn't exist, because I tried to get the 
sources there.  But I didn't know about the fork.  Please point me to it, or 
just make a tarball available to me somehow.



Here are the immediate contexts from the sources for the xemacs
sources in the above backtrace, might be enough to check your
hypothesis:

sysdep.c:

   retry_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
   {
 ssize_t rtnval;

 while ((rtnval = read (fildes, buf, nbyte)) == -1
    && (errno == EINTR)) 
   {
 if (allow_quit)
   QUIT;
   }
 return rtnval;
   }
I'll have to reproduce the hang myself in order to test this (or maybe you could 
test it), but I now have a new guess: If the read call above keeps failing with 
EINTR, then we're in an infinite loop.  This could happen because of the 
following code in fhandler_pipe::raw_read:


   DWORD waitret = cygwait (read_mtx, timeout);
   switch (waitret)
     {
     case WAIT_OBJECT_0:
   break;
     case WAIT_TIMEOUT:
   set_errno (EAGAIN);
   len = (size_t) -1;
   return;
     default:
   set_errno (EINTR);
   len = (size_t) -1;
   return;
     }

Takashi, is EINTR really the appropriate errno in the default case?  Isn't 
cygwait supposed to handle signals?


I was able to build XEmacs and reproduce the problem.  My guess was wrong, 
though my question to Takashi still stands.  I think the infinite loop is 
actually caused by a bug in fhandler_pipe::raw_read that only affects 
non-blocking pipes (which is what we have in XEmacs).


Consider the following code in fhandler_pipe::raw_read:

  status = NtReadFile (get_handle (), evt, NULL, NULL, &io, ptr,
   len1, NULL, NULL);
  if (evt && status == STATUS_PENDING)  
{
  waitret = cygwait (evt, INFINITE, cw_cancel | cw_sig);
[...]
}

In the non-blocking case, evt == NULL, but we still might have status == 
STATUS_PENDING.  We then should wait on get_handle() to let NtReadFile finish. 
By not waiting, we end up using a garbage value from io.Information, leading to 
an infinite loop in drain_signal_event_pipe.


I'll try to fix this.

Ken

--
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Henry S. Thompson via Cygwin
[private reply -- it's not exactly a private repo, but it's really not
 ready for prime-time with users expecting to be able to raise issues
 etc.]

Ken Brown writes:

> ...
> I was aware that the bitbucket repo didn't exist, because I tried to get the
> sources there.  But I didn't know about the fork.  Please point me to it, or
> just make a tarball available to me somehow.

https://foss.heptapod.net/xemacs

>> ...

> I'll have to reproduce the hang myself in order to test this (or
> maybe you could test it), but I now have a new guess: If the read
> call above keeps failing with EINTR, then we're in an infinite loop.

> This could happen because of the following code in
> fhandler_pipe::raw_read:
>
>   DWORD waitret = cygwait (read_mtx, timeout);
>   switch (waitret)
> {
> case WAIT_OBJECT_0:
>   break;
> case WAIT_TIMEOUT:
>   set_errno (EAGAIN);
>   len = (size_t) -1;
>   return;
> default:
>   set_errno (EINTR);
>   len = (size_t) -1;
>   return;
> }
>

Let's wait and see what Takashi says -- I see from github blame that
was introduced between 3.2 and 3.3.0, so certainly _could_ be the
culprit.  I've never tried to build my own Cygwin...

Thanks,

ht
-- 
   Henry S. Thompson, School of Informatics, University of Edinburgh
  10 Crichton Street, Edinburgh EH8 9AB, SCOTLAND -- (44) 131 650-4440
Fax: (44) 131 650-4587, e-mail: h...@inf.ed.ac.uk
   URL: http://www.ltg.ed.ac.uk/~ht/
 [mail from me _always_ has a .sig like this -- mail without it is forged spam]

The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.


-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Ken Brown via Cygwin

On 11/9/2021 5:55 AM, Henry S. Thompson wrote:

Ken Brown via Cygwin writes:


On 11/8/2021 8:12 AM, Henry S. Thompson via Cygwin wrote:

Running on Windows-10 21H1

With Cygwin 3.3.0 and 3.3.1 I get a hang every time I try to launch XEmacs:

..
#6  0x00018013ffcc in read (fd=3, ptr=0x0bc0, len=)
  at /usr/src/debug/cygwin-3.3.1-1/winsup/cygwin/dtable.h:64
#7  0x00018018e88b in _sigfe () at sigfe.s:35
#8  0x00010066a11d in retry_read_1 (fildes=3, buf=0x0bc0, nbyte=128,
  allow_quit=0) at sysdep.c:2425
#9  0x00010066a171 in retry_read (fildes=3, buf=0x0bc0, nbyte=128)
  at sysdep.c:2437
#10 0x000100494d86 in drain_signal_event_pipe () at event-unixoid.c:159
#11 0x00010056d1dc in mswindows_need_event (badly_p=1) at event-msw.c:1432

This is an old executable, has worked since 2015 (!), but recompiling
didn't help.  Reverting to 3.2 lets it run again.


This backtrace doesn't match the source of Cygwin's XEmacs package
(which exists on 32-bit Cygwin only), so I assume you built this
yourself, using a different version of XEmacs.  Cygwin's XEmacs
doesn't hang for me.


Thanks for looking in to this!

And you're right, it's a local build.  I was responsible for producing
the 64-bit XEmacs back in 2015, but could never get a Visual Studio
build to work at that time, so it was never released.


Please provide build instructions for the version you compiled.


As you may know, the XEmacs situation is complicated.  The old source
repo (bitbucket.org/xemacs) no longer exists.  There's a fork that's
still being maintained, but it's not widely publicised.  That's the
one I'm working with -- are you aware of this.


I was aware that the bitbucket repo didn't exist, because I tried to get the 
sources there.  But I didn't know about the fork.  Please point me to it, or 
just make a tarball available to me somehow.



Here are the immediate contexts from the sources for the xemacs
sources in the above backtrace, might be enough to check your
hypothesis:

sysdep.c:

   retry_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
   {
 ssize_t rtnval;

 while ((rtnval = read (fildes, buf, nbyte)) == -1
&& (errno == EINTR)) 
   {
 if (allow_quit)
   QUIT;
   }
 return rtnval;
   }
I'll have to reproduce the hang myself in order to test this (or maybe you could 
test it), but I now have a new guess: If the read call above keeps failing with 
EINTR, then we're in an infinite loop.  This could happen because of the 
following code in fhandler_pipe::raw_read:


  DWORD waitret = cygwait (read_mtx, timeout);
  switch (waitret)
{
case WAIT_OBJECT_0:
  break;
case WAIT_TIMEOUT:
  set_errno (EAGAIN);
  len = (size_t) -1;
  return;
default:
  set_errno (EINTR);
  len = (size_t) -1;
  return;
}

Takashi, is EINTR really the appropriate errno in the default case?  Isn't 
cygwait supposed to handle signals?


Ken

--
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Hope I Haven’t Offended

2021-11-09 Thread Nataliya Kalava
Hi,

Hope my note finds you well.

I would like to send you a target B2B list. We can help you reach out to your 
specific prospects effectively.

Industries: - Healthcare, Technology, Financial, Transportation, Retail, Media, 
Manufacturing, Aerospace, Automotive, Hospitality, Electronics, Food & 
Beverage, Construction, Educational, HVAC, Leasing etc.

If you would like to review a tester file, let us know your list parameters i.e.

Industrial Sectors you serve across: -  _?
Job Titles you wish to contact: -__ _?
Geographic locations of your reach: -?

Looking forward to delivering customized and quality tester leads upon your 
request.

Thank you for your time and we hope to hear from you soon.

Regards,
Nataliya Kalava
Sr. Business Development Manager.

Note: If you do not wish to receive our emails you can reply “Not Interested” 
in the subject line.


-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Another pipe-related problem?

2021-11-09 Thread Henry S. Thompson via Cygwin
Ken Brown via Cygwin writes:

> On 11/8/2021 8:12 AM, Henry S. Thompson via Cygwin wrote:
>> Running on Windows-10 21H1
>>
>> With Cygwin 3.3.0 and 3.3.1 I get a hang every time I try to launch XEmacs:
>>
>> ..
>> #6  0x00018013ffcc in read (fd=3, ptr=0x0bc0, len=)
>>  at /usr/src/debug/cygwin-3.3.1-1/winsup/cygwin/dtable.h:64
>> #7  0x00018018e88b in _sigfe () at sigfe.s:35
>> #8  0x00010066a11d in retry_read_1 (fildes=3, buf=0x0bc0, nbyte=128,
>>  allow_quit=0) at sysdep.c:2425
>> #9  0x00010066a171 in retry_read (fildes=3, buf=0x0bc0, nbyte=128)
>>  at sysdep.c:2437
>> #10 0x000100494d86 in drain_signal_event_pipe () at event-unixoid.c:159
>> #11 0x00010056d1dc in mswindows_need_event (badly_p=1) at 
>> event-msw.c:1432
>>
>> This is an old executable, has worked since 2015 (!), but recompiling
>> didn't help.  Reverting to 3.2 lets it run again.
>
> This backtrace doesn't match the source of Cygwin's XEmacs package
> (which exists on 32-bit Cygwin only), so I assume you built this
> yourself, using a different version of XEmacs.  Cygwin's XEmacs
> doesn't hang for me.

Thanks for looking in to this!

And you're right, it's a local build.  I was responsible for producing
the 64-bit XEmacs back in 2015, but could never get a Visual Studio
build to work at that time, so it was never released.

> Please provide build instructions for the version you compiled.

As you may know, the XEmacs situation is complicated.  The old source
repo (bitbucket.org/xemacs) no longer exists.  There's a fork that's
still being maintained, but it's not widely publicised.  That's the
one I'm working with -- are you aware of this.

> Your backtrace shows that fhandler_pipe::raw_read is blocked waiting
> for a mutex, but I can't tell why without seeing the XEmacs source.
> My guess, just from looking at the function names, is that XEmacs is
> mixing POSIX reads with Win32 reads, messing up the mutex handling.

If you have access to the public sources vintage mid-2015 or later,
the following might work:

  ./configure  '--with-pdump=yes' '--with-modules=no' '--with-mule=yes' 
'--with-ncurses=yes' '--with-msw=yes' '--with-xpm' '--with-tls=no' '--without-x'
  make
  src/xemacs --vanilla

Otherwise let me know and I'll point you at the current repo.

Here are the immediate contexts from the sources for the xemacs
sources in the above backtrace, might be enough to check your
hypothesis:

sysdep.c:

  retry_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
  {
ssize_t rtnval;

while ((rtnval = read (fildes, buf, nbyte)) == -1
   && (errno == EINTR))
  {
if (allow_quit)
  QUIT;
  }
return rtnval;
  }

  ssize_t
  retry_read (int fildes, void *buf, size_t nbyte)
  {
return retry_read_1 (fildes, buf, nbyte, 0);
  }

event-unixoid.c:

  drain_signal_event_pipe (void)
  {
Rawbyte chars[128];
/* The input end of the pipe has been set to non-blocking. */
while (retry_read (signal_event_pipe[0], chars, sizeof (chars)) > 0)
  ;
  }

event-msw.c:

  /*
   * This drains the event queue and fills up two internal queues until
   * an event of a type specified by USER_P is retrieved.
   *
   *
   * Used by emacs_mswindows_event_pending_p and emacs_mswindows_next_event
   */
  static void
  mswindows_need_event (int badly_p)
  {
while (NILP (dispatch_event_queue)
   && NILP (mswindows_s_dispatch_event_queue))
  {
  #ifdef CYGWIN
int i;
int active;
SELECT_TYPE temp_mask = input_wait_mask;
EMACS_TIME sometime;
EMACS_SELECT_TIME select_time_to_block, *pointer_to_this;

if (badly_p)
  pointer_to_this = 0;
else
  {
EMACS_SET_SECS_USECS (sometime, 0, 0);
EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block);
pointer_to_this = &select_time_to_block;
if (in_modal_loop)
  /* In modal loop with badly_p false, don't care about
 Windows events. */
  FD_CLR (windows_fd, &temp_mask);
  }

mswindows_is_blocking = 1;
active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this);
mswindows_is_blocking = 0;

if (active == 0)
  {
assert (!badly_p);
return;   /* timeout */
  }
else if (active > 0)
  {
if (FD_ISSET (windows_fd, &temp_mask))
  mswindows_drain_windows_queue (badly_p);
else
  {
  #ifdef HAVE_TTY
/* Look for a TTY event */
for (i = 0; i < MAXDESC; i++)
  {
/* To avoid race conditions (among other things, an infinite
   loop when called from Fdiscard_input()), we must return
   user events ahead of process events. */
if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, 
&tty_only_mask))