Subject: bug#32452: 26.1; gnutls_try_handshake maxes out cpu retrying when server is a bit busy

From: Lars Ingebrigtsen <[email-masked]>
Date: Tue, 01 Mar 2022 16:36:03 +0100

Paul Eggert <[email-masked]> writes:

> Evidently my recent workarounds in Emacs to handle running gnulib-tool
> from a bare checkout were not sufficient. I installed the attached
> patch to up the ante; please give it a try.
>
> It is unfortunate that emacs/admin/merge-gnulib now runs gnulib-tool
> twice from a bare checkout, as gnulib-tool is quite slow.

My latest attempt wasn't from a bare checkout -- it was from my normal
development tree, though.

In any case, doing this:

diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 7219fadd47..074101f095 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -40,7 +40,7 @@ GNULIB_MODULES=
   getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog
   ieee754-h ignore-value intprops largefile libgmp lstat
   manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime
-  nproc nstrftime
+  nanosleep nproc nstrftime
   pathmax pipe2 pselect pthread_sigmask
   qcopy-acl readlink readlinkat regex
   sig2str sigdescr_np socklen stat-time std-gnu11 stdalign stddef stdio

Then running admin/merge-gnulib, and then adding this:

diff --git a/src/gnutls.c b/src/gnutls.c
index 3ec3837067..5389b15b1e 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -616,6 +616,7 @@ gnutls_try_handshake (struct Lisp_Process *proc)
   gnutls_session_t state = proc->gnutls_state;
   int ret;
   bool non_blocking = proc->is_non_blocking_client;
+  struct timespec delay = { 0, 1000 * 1000 * 10 };
 
   if (proc->gnutls_complete_negotiation_p)
     non_blocking = false;
@@ -630,6 +631,7 @@ gnutls_try_handshake (struct Lisp_Process *proc)
       maybe_quit ();
       if (non_blocking && ret != GNUTLS_E_INTERRUPTED)
 	break;
+      nanosleep (&delay, NULL);
     }
 
   proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;

Still leads to:

/usr/bin/ld: gnutls.o: in function `gnutls_try_handshake':
/home/larsi/src/emacs/gtest/src/gnutls.c:634: undefined reference to `rpl_nanosleep'
collect2: error: ld returned 1 exit status

Are there any further incantations needed to use stuff from gnulib?  I
tried to compare with other usages of gnulib stuff, and nothing really
stood out immediately.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no