Comment 20 for bug 182923

Revision history for this message
Richard Schwarting (aquarichy) wrote :

SUMMARY:
 in mn_client_session_run(), avoiding attempting to close(session.s) when we haven't set session.s (but which is initialised to 0 by memset) prevents mail-notification (according to top) from hogging my CPU when offline.

DETAILS:
I got tired of having this interrupt watching movies (my laptop is only fast enough to handle mplayer or mail-notification hogging the CPU, not both :D), so using ltrace, gdb, and sysprof, I decided that the problem was Evil and Trying to Hide.

So, after instrumenting the code with a few hundred mn_info() statements and a couple sleep(10)s (to find out when the CPU went crazy), and repeatedly trying Mike's reproduction instructions, I found a point at which the CPU starts going 100%.

in mn-client-session.c in mn_client_session_run(), session is set and its property session.s gets indirectly initialised to 0.

session.s might get set by client_session_connect(), if we get that far. When my network is disconnected, and this code is run, I don't get past the check after "addrinfo = resolve(&session);", though, so session.s isn't set, and I go to the end label.

The first thing done at the label end: is a check to see whether session.s >= 0 (which it will be, since memset indirectly initialised it to 0) and we call mn_close(session.s).

Now, it doesn't seem that we remain in mn_close in a loop at all, but after calling close(fd), my CPU will go to 100%. (That is, if in mn_close, if I do:
* sleep(10);
* do status = close(fd) while (status < 0 && errno == EINTR);
* // now the CPU goes up to 100%, not during the first sleep period, but visible during the second, after close()
* sleep(10);

My change was to explicitly initialise session.s to -1 in mn_client_session_run(), so that we wouldn't attempt to close it with the value 0 if we never actually set it to a file.

I'm not yet sure why the CPU would go to 100%. I'll poke into that now.