* gnutls infloop possibly fixed @ 2012-02-11 17:10 Lars Ingebrigtsen 2012-02-12 2:48 ` Ted Zlatanov 0 siblings, 1 reply; 11+ messages in thread From: Lars Ingebrigtsen @ 2012-02-11 17:10 UTC (permalink / raw) To: emacs-devel I finally took a hard look at the GnuTLS-related Emacs hangs. It turned out to be pretty easy to reproduce for me. If I switch off the wifi on this laptop and then presses `g' in Gnus, Emacs would reliably use 100% CPU, and `C-g' or anything wouldn't work. So a totally dead Emacs. I chased this down to emacs_gnutls_write, which would just, well, infloop if libgnutls returned EAGAIN. I've now removed that, and just leaves the normal Emacs process loop to retry if we get an EAGAIN. This seems to work for me -- `C-g' reliably works for me if I drop the network, or I get a new IP address. There may be other side-effects, though. Slower throughput? I don't know. Please give it a whirl and report back whether things stop working or not. -- (domestic pets only, the antidote for overdose, milk.) http://lars.ingebrigtsen.no * Sent from my Rome ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-11 17:10 gnutls infloop possibly fixed Lars Ingebrigtsen @ 2012-02-12 2:48 ` Ted Zlatanov 2012-02-12 19:47 ` Lars Ingebrigtsen 0 siblings, 1 reply; 11+ messages in thread From: Ted Zlatanov @ 2012-02-12 2:48 UTC (permalink / raw) To: emacs-devel On Sat, 11 Feb 2012 18:10:23 +0100 Lars Ingebrigtsen <larsi@gnus.org> wrote: LI> I finally took a hard look at the GnuTLS-related Emacs hangs. It turned LI> out to be pretty easy to reproduce for me. If I switch off the wifi on LI> this laptop and then presses `g' in Gnus, Emacs would reliably use 100% LI> CPU, and `C-g' or anything wouldn't work. So a totally dead Emacs. LI> I chased this down to emacs_gnutls_write, which would just, well, LI> infloop if libgnutls returned EAGAIN. I've now removed that, and just LI> leaves the normal Emacs process loop to retry if we get an EAGAIN. LI> This seems to work for me -- `C-g' reliably works for me if I drop the LI> network, or I get a new IP address. LI> There may be other side-effects, though. Slower throughput? I don't LI> know. Please give it a whirl and report back whether things stop LI> working or not. Thanks! I have just one question: can we, instead of aborting on EAGAIN, retry a few times? My suggestion is below. Maybe we could wait a millisecond, too. Or is all that handled at the Emacs process loop level? Thanks Ted === modified file 'src/gnutls.c' --- src/gnutls.c 2012-02-11 17:06:14 +0000 +++ src/gnutls.c 2012-02-12 02:46:24 +0000 @@ -341,6 +341,7 @@ EMACS_INT emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte) { + int retries = 10; ssize_t rtnval = 0; EMACS_INT bytes_written; gnutls_session_t state = proc->gnutls_state; @@ -365,6 +366,8 @@ { if (rtnval == GNUTLS_E_INTERRUPTED) continue; + if (rtnval == GNUTLS_E_AGAIN && retries-- > 0) + continue; else break; } ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-12 2:48 ` Ted Zlatanov @ 2012-02-12 19:47 ` Lars Ingebrigtsen 2012-02-12 21:34 ` Ted Zlatanov ` (2 more replies) 0 siblings, 3 replies; 11+ messages in thread From: Lars Ingebrigtsen @ 2012-02-12 19:47 UTC (permalink / raw) To: emacs-devel Ted Zlatanov <tzz@lifelogs.com> writes: > Thanks! I have just one question: can we, instead of aborting on > EAGAIN, retry a few times? My suggestion is below. That would make sense, I guess. I have no idea whether EAGAIN is a common situation to be in when doing writes on a functioning network, though. That is, if EAGAIN "never" happens when the network is up, then adding the loop doesn't help any. But it doesn't hurt, either, so... > Maybe we could wait a millisecond, too. Or is all that handled at the > Emacs process loop level? The Emacs process loop will eventually try to write the stuff out again, but how long it takes can be pretty random. If Emacs is idle, it retries about once a second, I think? But if we've just said `process-send-string' and then is in an `accept-process-output' loop (which would be the common case), then it'll probably be retried sooner? Perhaps? Hey, I can just test that now by taking down the network and hitting `g'... let's see... Ok: [pid 5621] 20:45:22 sendto(13, "p`q\214\\\37\354\20QD\215\272$\t\241\347\273\343\316\322\247", 21, 0, NULL, 0) = -1 EAGAIN (Resource temporarily unavailable) [pid 5621] 20:45:22 sendto(13, "p`q\214\\\37\354\20QD\215\272$\t\241\347\273\343\316\322\247", 21, 0, NULL, 0) = -1 EAGAIN (Resource temporarily unavailable) [pid 5621] 20:45:22 sendto(13, "p`q\214\\\37\354\20QD\215\272$\t\241\347\273\343\316\322\247", 21, 0, NULL, 0) = -1 EAGAIN (Resource temporarily unavailable) (etc) It seems to retry the GnuTLS sendto about 20 times a second in the `g' test. I think that's probably more than good enough, and adding an extra loop there isn't necessary. -- (domestic pets only, the antidote for overdose, milk.) http://lars.ingebrigtsen.no * Sent from my Rome ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-12 19:47 ` Lars Ingebrigtsen @ 2012-02-12 21:34 ` Ted Zlatanov 2012-02-13 15:48 ` Tom Tromey 2012-02-13 21:41 ` Richard Stallman 2 siblings, 0 replies; 11+ messages in thread From: Ted Zlatanov @ 2012-02-12 21:34 UTC (permalink / raw) To: emacs-devel On Sun, 12 Feb 2012 20:47:14 +0100 Lars Ingebrigtsen <larsi@gnus.org> wrote: LI> Ted Zlatanov <tzz@lifelogs.com> writes: >> Thanks! I have just one question: can we, instead of aborting on >> EAGAIN, retry a few times? My suggestion is below. ... LI> It seems to retry the GnuTLS sendto about 20 times a second in the `g' LI> test. I think that's probably more than good enough, and adding an LI> extra loop there isn't necessary. Cool, thanks for testing that. I really appreciate your fix. Ted ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-12 19:47 ` Lars Ingebrigtsen 2012-02-12 21:34 ` Ted Zlatanov @ 2012-02-13 15:48 ` Tom Tromey 2012-02-13 19:11 ` Lars Ingebrigtsen 2012-02-13 21:41 ` Richard Stallman 2 siblings, 1 reply; 11+ messages in thread From: Tom Tromey @ 2012-02-13 15:48 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: emacs-devel >>>>> "Lars" == Lars Ingebrigtsen <larsi@gnus.org> writes: Lars> That would make sense, I guess. I have no idea whether EAGAIN is a Lars> common situation to be in when doing writes on a functioning network, Lars> though. I use one nntp server that causes Emacs to pause for quite a while as it works something out during the connection. If I strace Emacs, I see it looping on select -> read -> EAGAIN. Then eventually something happens and things return back to normal. I'm wondering whether this is a bug in GNUTLS, or Emacs' use thereof, or the server. Any ideas offhand? Tom ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-13 15:48 ` Tom Tromey @ 2012-02-13 19:11 ` Lars Ingebrigtsen 2012-02-13 19:39 ` Lars Ingebrigtsen 0 siblings, 1 reply; 11+ messages in thread From: Lars Ingebrigtsen @ 2012-02-13 19:11 UTC (permalink / raw) To: Tom Tromey; +Cc: emacs-devel Tom Tromey <tromey@redhat.com> writes: > I use one nntp server that causes Emacs to pause for quite a while as it > works something out during the connection. If I strace Emacs, I see it > looping on select -> read -> EAGAIN. Then eventually something happens > and things return back to normal. A read -> EAGAIN normally means that the server didn't return anything (much). So it kinda sounds like a slow NNTP server. -- (domestic pets only, the antidote for overdose, milk.) http://lars.ingebrigtsen.no * Sent from my Rome ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-13 19:11 ` Lars Ingebrigtsen @ 2012-02-13 19:39 ` Lars Ingebrigtsen 2012-02-13 20:46 ` Andreas Schwab 0 siblings, 1 reply; 11+ messages in thread From: Lars Ingebrigtsen @ 2012-02-13 19:39 UTC (permalink / raw) To: emacs-devel I had a bug report of a strange file-error "success" being reported by a Gnus user, and I applied the following patch. It sets errno to EAGAIN if GnuTLS returns EAGAIN. Does this make sense, or is it just cargo-cult programming? === modified file 'src/gnutls.c' *** src/gnutls.c 2012-02-11 17:06:14 +0000 --- src/gnutls.c 2012-02-13 19:35:30 +0000 *************** *** 365,372 **** { if (rtnval == GNUTLS_E_INTERRUPTED) continue; ! else break; } buf += rtnval; --- 365,384 ---- { if (rtnval == GNUTLS_E_INTERRUPTED) continue; ! else { ! /* If we get EAGAIN, then set errno appropriately so that ! send_process retries the correct way instead of ! erroring out. */ ! if (rtnval == EAGAIN) { ! #ifdef EWOULDBLOCK ! errno = EWOULDBLOCK; ! #endif ! #ifdef EAGAIN ! errno = EAGAIN; ! #endif ! } break; + } } buf += rtnval; -- (domestic pets only, the antidote for overdose, milk.) http://lars.ingebrigtsen.no * Sent from my Rome ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-13 19:39 ` Lars Ingebrigtsen @ 2012-02-13 20:46 ` Andreas Schwab 2012-02-13 20:47 ` Lars Ingebrigtsen 0 siblings, 1 reply; 11+ messages in thread From: Andreas Schwab @ 2012-02-13 20:46 UTC (permalink / raw) To: emacs-devel Lars Ingebrigtsen <larsi@gnus.org> writes: > ! if (rtnval == EAGAIN) { That is never true. > ! #ifdef EWOULDBLOCK > ! errno = EWOULDBLOCK; > ! #endif > ! #ifdef EAGAIN > ! errno = EAGAIN; > ! #endif Does this actually survive emacs_gnutls_handle_error? Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-13 20:46 ` Andreas Schwab @ 2012-02-13 20:47 ` Lars Ingebrigtsen 0 siblings, 0 replies; 11+ messages in thread From: Lars Ingebrigtsen @ 2012-02-13 20:47 UTC (permalink / raw) To: Andreas Schwab; +Cc: emacs-devel Andreas Schwab <schwab@linux-m68k.org> writes: >> ! if (rtnval == EAGAIN) { > > That is never true. D'oh. It's GNUTLS_E_EAGAIN, I guess. -- (domestic pets only, the antidote for overdose, milk.) http://lars.ingebrigtsen.no * Sent from my Rome ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-12 19:47 ` Lars Ingebrigtsen 2012-02-12 21:34 ` Ted Zlatanov 2012-02-13 15:48 ` Tom Tromey @ 2012-02-13 21:41 ` Richard Stallman 2012-02-13 22:05 ` Andreas Schwab 2 siblings, 1 reply; 11+ messages in thread From: Richard Stallman @ 2012-02-13 21:41 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: emacs-devel > Thanks! I have just one question: can we, instead of aborting on > EAGAIN, retry a few times? My suggestion is below. That would make sense, I guess. I have no idea whether EAGAIN is a common situation to be in when doing writes on a functioning network, though. EAGAIN is defined to mean that a system call was interrupted and the program should try again. -- Dr Richard Stallman President, Free Software Foundation 51 Franklin St Boston MA 02110 USA www.fsf.org www.gnu.org Skype: No way! That's nonfree (freedom-denying) software. Use free telephony http://directory.fsf.org/category/tel/ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: gnutls infloop possibly fixed 2012-02-13 21:41 ` Richard Stallman @ 2012-02-13 22:05 ` Andreas Schwab 0 siblings, 0 replies; 11+ messages in thread From: Andreas Schwab @ 2012-02-13 22:05 UTC (permalink / raw) To: rms; +Cc: Lars Ingebrigtsen, emacs-devel Richard Stallman <rms@gnu.org> writes: > EAGAIN is defined to mean that a system call was interrupted and the > program should try again. That's EINTR. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2012-02-13 22:05 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-02-11 17:10 gnutls infloop possibly fixed Lars Ingebrigtsen 2012-02-12 2:48 ` Ted Zlatanov 2012-02-12 19:47 ` Lars Ingebrigtsen 2012-02-12 21:34 ` Ted Zlatanov 2012-02-13 15:48 ` Tom Tromey 2012-02-13 19:11 ` Lars Ingebrigtsen 2012-02-13 19:39 ` Lars Ingebrigtsen 2012-02-13 20:46 ` Andreas Schwab 2012-02-13 20:47 ` Lars Ingebrigtsen 2012-02-13 21:41 ` Richard Stallman 2012-02-13 22:05 ` Andreas Schwab
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).