nettester So there either has to be some kind of code that ignores return codes turning something that should really wait for data into an eternal spinlock or said return codes are bogus (like select instantly returning without failure but no events despite timeout) and thus tricking mutt into thinking everything is fine.
Another scenario is the system-time going backwards across a suspend, and
mutt not expecting that to happen.
For example, see the
raw_socket_poll() function in
mutt_socket.c. It uses
gettimeofday() pairs to (portably) determine if
select() returned with a "short" sleep, and then compensate for that. The way it does this is fine in most cases--except if the second
gettimeofday() returns a time before that of the first
gettimeofday(). Then the code will sleep for much longer than anticipated.
gettimeofday() should not be used for monotonic time intervals. If you want a monotonic interval, the system generally provides a better one.
@szilard Please try this patch:
diff -urN mutt-2.2.10.orig/mutt_socket.c mutt-2.2.10/mutt_socket.c
--- mutt-2.2.10.orig/mutt_socket.c 2023-03-25 19:50:20.000000000 +0000
+++ mutt-2.2.10/mutt_socket.c 2023-07-21 14:10:02.712062000 +0000
@@ -517,7 +517,8 @@
unsigned long long wait_millis, post_t_millis;
- struct timeval tv, pre_t, post_t;
+ struct timeval tv;
+ struct timespec pre_t, post_t;
if (conn->fd < 0)
@@ -533,9 +534,9 @@
FD_SET (conn->fd, &rfds);
- gettimeofday (&pre_t, NULL);
+ clock_gettime (CLOCK_MONOTONIC, &pre_t);
rv = select (conn->fd + 1, &rfds, NULL, NULL, &tv);
- gettimeofday (&post_t, NULL);
+ clock_gettime (CLOCK_MONOTONIC, &post_t);
if (rv > 0 ||
(rv < 0 && errno != EINTR))
@@ -545,9 +546,9 @@
wait_millis += ((unsigned long long)pre_t.tv_sec * 1000ULL) +
- (unsigned long long)(pre_t.tv_usec / 1000);
+ (unsigned long long)(pre_t.tv_nsec / (1000 * 1000));
post_t_millis = ((unsigned long long)post_t.tv_sec * 1000ULL) +
- (unsigned long long)(post_t.tv_usec / 1000);
+ (unsigned long long)(post_t.tv_nsec / (1000 * 1000));
if (wait_millis <= post_t_millis)
wait_millis -= post_t_millis;
EDIT: Upon reflection, this scenario would only result in unwanted sleeps, not the high CPU-loading you observed. So, compile
mutt for debugging and run it in the debugger. We should be able to see what's spinning.