Subject: bug#50043: 28.0.50; USABLE_SIGOI undef code paths do not work correctly

From: Ken Brown <[email-masked]>
Date: Wed, 17 Nov 2021 12:25:38 -0500

On 11/17/2021 11:57 AM, Eli Zaretskii wrote:
>> Date: Wed, 17 Nov 2021 09:59:35 -0500
>> Cc: [email-masked], [email-masked]
>> From: Ken Brown <[email-masked]>
>>
>>> But maybe it will be better to do it the same way we
>>> decrease the timeout when a timer is expected to expire before the
>>> timeout: we decrease the timeout, but still remember its value, and
>>> don't return from waiting before the timeout unless there really was
>>> some input.  This would avoid affecting unrelated features such as
>>> accept-process-output.
>>
>> I think that's already taken care of.  The timeout is recalculated on each
>> iteration of the main while loop:
>>
>>         /* Compute time from now till when time limit is up.  */
>>         /* Exit if already run out.  */
>>         if (wait == TIMEOUT)
>> 	{
>> 	  if (!timespec_valid_p (now))
>> 	    now = current_timespec ();
>> 	  if (timespec_cmp (end_time, now) <= 0)
>> 	    break;
>> 	  timeout = timespec_sub (end_time, now);
>> 	}
>>         else
>> 	timeout = make_timespec (wait < TIMEOUT ? 0 : 100000, 0);
>>
>> My reduction of timeout to 25 msec occurs after this.
> 
> So the result will be that on systems without USABLE_SIGIO we loop
> more times with shorter timeouts for select?

Yes.

> If so, it SGTM.

Thanks, I've pushed that change.

There's still one more issue related to this bug, which I mentioned earlier: If 
x_selection_timeout is zero, x_get_foreign_selection will call 
wait_reading_process output with an infinite timeout rather than a zero timeout, 
which I'm sure is not what was intended.  The attached patch fixes that.

Ken

From 5a0afdf1cb2ef276a2b6e4cf26abf18405127db2 Mon Sep 17 00:00:00 2001
From: Ken Brown <[email-masked]>
Date: Wed, 17 Nov 2021 12:20:24 -0500
Subject: [PATCH] Avoid an accidental use of an infinite timeout

* src/xselect.c (x_get_foreign_selection): If x-selection-timeout
is zero, call wait_reading_process_output with a zero timeout
rather than an infinite timeout.  (Bug#50043)
---
 src/xselect.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/xselect.c b/src/xselect.c
index cd6d86bdf4..53b41f1ea2 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1196,6 +1196,10 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
   intmax_t timeout = max (0, x_selection_timeout);
   intmax_t secs = timeout / 1000;
   int nsecs = (timeout % 1000) * 1000000;
+  /* If x_selection_timeout == 0, avoid the "zero means infinite"
+     behavior of wait_reading_process_output. */
+  if (secs == 0 && nsecs == 0)
+    nsecs = -1;
   TRACE1 ("  Start waiting %"PRIdMAX" secs for SelectionNotify", secs);
   wait_reading_process_output (secs, nsecs, 0, false,
 			       reading_selection_reply, NULL, 0);
-- 
2.33.0