Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Busy loop when poll/epoll is in use #4605

Closed
michaelrsweet opened this issue Mar 11, 2015 · 5 comments
Closed

Busy loop when poll/epoll is in use #4605

michaelrsweet opened this issue Mar 11, 2015 · 5 comments
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 2.0-current
CUPS.org User: twaugh.redhat

epoll_wait() will always wait for EPOLL_HUP even if event.events==0. This causes a busy loop when a connection is closed just after this moment, in scheduler/client.c:1980:

if (httpGetState(con->http) == HTTP_STATE_POST_SEND)
{

/*
* Don't listen for activity until we decide to do something with this...
*/

cupsdAddSelect(httpGetFd(con->http), NULL, NULL, con);

This causes an event with event.events==0 to be added/modified with epoll_ctl().

Original report:
https://bugzilla.redhat.com/show_bug.cgi?id=1179596

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: twaugh.redhat

Actually this happens with plain poll() as well, at least on Linux:

poll([{fd=3, events=POLLIN}, {fd=10, events=POLLIN}, {fd=11, events=POLLIN}, {fd=12, events=POLLIN}, {fd=15, events=0}, {fd=16, events=0}], 6, 1000) = 2 ([{fd=15, revents=POLLHUP}, {fd=16, revents=POLLHUP}])
poll([{fd=3, events=POLLIN}, {fd=10, events=POLLIN}, {fd=11, events=POLLIN}, {fd=12, events=POLLIN}, {fd=15, events=0}, {fd=16, events=0}], 6, 1000) = 2 ([{fd=15, revents=POLLHUP}, {fd=16, revents=POLLHUP}])
poll([{fd=3, events=POLLIN}, {fd=10, events=POLLIN}, {fd=11, events=POLLIN}, {fd=12, events=POLLIN}, {fd=15, events=0}, {fd=16, events=0}], 6, 1000) = 2 ([{fd=15, revents=POLLHUP}, {fd=16, revents=POLLHUP}])
poll([{fd=3, events=POLLIN}, {fd=10, events=POLLIN}, {fd=11, events=POLLIN}, {fd=12, events=POLLIN}, {fd=15, events=0}, {fd=16, events=0}], 6, 1000) = 2 ([{fd=15, revents=POLLHUP}, {fd=16, revents=POLLHUP}])
[...]

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: twaugh.redhat

Here's the fix I'm using. Rather than removing the callbacks, leave them in place and deal with the consequences. This is sort of what was already happening before the call to cupsdAddSelect(..., NULL, NULL, ...) was added.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in Subversion repository.

@michaelrsweet
Copy link
Collaborator Author

"cups-busy-loop.patch":

diff -up cups-2.0.2/scheduler/client.c.busy-loop cups-2.0.2/scheduler/client.c
--- cups-2.0.2/scheduler/client.c.busy-loop 2014-08-28 16:37:22.000000000 +0100
+++ cups-2.0.2/scheduler/client.c 2015-03-16 17:24:32.506232983 +0000
@@ -585,6 +585,17 @@ cupsdReadClient(cupsd_client_t con) /
* connection and we need to shut it down...
*/

  • if (!httpGetReady(con->http) && recv(httpGetFd(con->http), buf, 1, MSG_PEEK) < 1)
  • {
  • /*
    
  •  \* Connection closed...
    
  •  */
    
  •  cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on EOF.");
    
  •  cupsdCloseClient(con);
    
  •  return;
    
  • }

cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on unexpected HTTP read state %s.",
httpStateString(httpGetState(con->http)));
cupsdCloseClient(con);
@@ -1979,12 +1990,6 @@ cupsdReadClient(cupsd_client_t con) /

if (httpGetState(con->http) == HTTP_STATE_POST_SEND)
{

  • /*
  • \* Don't listen for activity until we decide to do something with this...
    

- */

- cupsdAddSelect(httpGetFd(con->http), NULL, NULL, con);

  if (con->file >= 0)
  {
    fstat(con->file, &filestats);

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: till.kamppeter

Probably this Ubuntu bug report treats the same bug:

https://bugs.launchpad.net/bugs/1426490

@michaelrsweet michaelrsweet added this to the Stable milestone Mar 17, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant