-
Notifications
You must be signed in to change notification settings - Fork 467
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
cupsd blocked in read(2) #1157
Comments
CUPS.org User: mike I believe this is a bug we fixed a while back (checking the revision history, looks like it was fixed in CUPS 1.1.19) - the current code clears the main() input set bit:
Which version of CUPS did you import from? |
CUPS.org User: jlovell You did fix the case where UpdateJob starts a new job (the usual path to job completion / next job starting) but not when ReadClient puts a job on hold or cancels it. Thanks! |
CUPS.org User: mike OK, probably the easiest fix is to move the client checking AFTER all of the job checking (or visa-versa) so that that condition can't occur... :) I really don't want to make the main() FD_SET global, since it is really just transient state info... Try the attached patch and let me know if that fixes things for you... |
CUPS.org User: jlovell Hmm... I think it can still be a problem between two calls to ReadClient. if the first call causes CloseClient to be called (invalid IPP request) and the second starts a cgi such that a reused 'con->file' is added to InputSet then WriteClient() can block trying to read the cgi data. Sound possible? Thanks. |
CUPS.org User: mike Hmm, possibly. Try the additional patch below which will take care of that edge case... |
CUPS.org User: jlovell I think there's still a small window here... WriteClient gets an error closing the fd, next ReadClient starts a cgi, a following WriteClient then blocks reading cgi data. It might be enough to "FD_CLR(con->file, input)" no matter the return value from ReadClient. It's a little worse in our main() because mdns (Bonjour)involves opening & closing sockets when printers come & go. This provides another opportunity to reuse an fd. I'll track your changes but I'll probably also go with my original plan of adding FD_CLRs of a global 'input' since it removes all the ordering issues. Thanks! |
CUPS.org User: mike Sorry I didn't respond sooner, still in the "get everything commited to 1.2" mode... :) OK, so if I understand the issue correctly, it is the non-clearing of the output set here:
If so, then the attached patch should clear things up (literally :) without making the transient locale input or output sets global. I might look at adding cupsdSetInput, cupsdSetOutput, cupsdClearInput, and cupsdClearOutput calls in CUPS 1.2 which manage both the current global sets as well as the sets used by the main() loop... |
CUPS.org User: jlovell Thanks. I think the patch solves the WriteClient case. I have some mostly completed code that implements something like what you suggest; the goal was to add encapsulated support for select(2), poll(2) and kqueue(2). The SPI looks something like: extern int cupsPollInit(); The general idea came from: (I found this when was using his excellent ISDN info back when I used one of those cool dual channel ISDN modems -- Ha!) |
CUPS.org User: mike Feel free to send a patch in a separate STR for the poller SPI - it might come in useful for future porting work... |
"str1157.patch": Index: main.c--- main.c (revision 4504)
for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
for (i = NumClients, con = Clients; i > 0; i --, con ++) /*
- */
- next = job->next;
- */- FD_CLR(job->pipe, input);
- */
- }
- */
- UpdateCGI();
- */
- UpdateCUPSBrowse();
- UpdatePolling();-#ifdef HAVE_LIBSLP
- }
|
"str1157part2.patch": Index: main.c--- main.c (revision 4509)
|
"str1157part3.patch": Index: main.c--- main.c (revision 4515)
|
Version: 1.1-current
CUPS.org User: jlovell
I received a bug saying a busy cupsd can become blocked with the following backtrace:
Analysis of sampling pid 2216 every 10.000000 milliseconds
Call graph:
4998 Thread_0e0b
4998 start (in cupsd) (ipp.c:1017)
4998 __start (in cupsd) (crt.c:267)
4998 _main (in cupsd) (main.c:633)
4998 _UpdateJob (in cupsd) (job.c:2134)
4998 read
My theory is file descriptors can be reused within one pass of the main select loop. It goes something like this:
A fix is to make the local fd_set 'input' a global and wherever we see this kind of code:
add a:
FD_CLR(current->pipe, input);
Thoughts?
Thanks
The text was updated successfully, but these errors were encountered: