Recoup on:
Re^6: Trying to thread a daemon with threads and Thread::Queue
The following part of the code (in the handleConnection() sub) has a serious flaw:
shutdown $socket, 2;
From:
perldoc on shutdown()
"It's also a more insistent form of close because it also disables the file descriptor in any forked copies in other processes."
The thread tries to force closing the socket using shutdown() (after the thread is done with the connection) while the main accept thread still has it open, causing the script to abnormally terminate without any errors messages.
Removing this line from the handleConnection() sub and keeping only "close socket;", re-running the script, then simulating a client connection and request returns the expected data, but the client sees the connection still open (because the socket wasn't closed from server)
This is due to the construct of the main accept thread:
while ( my ($new_sock, $clientAddr) = $sock->accept() )
{
my ( $clientPort, $clientIp ) = sockaddr_in( $clientAddr );
# put the connection on the queue for a reader thread
my $fno = fileno($new_sock);
$sockets{ $fno } = $new_sock;
$Q->enqueue( "$fno\0$clientIp" );
while ( $Qclean->pending )
{
my $fileno = $Qclean->dequeue();
$log->warning("Attempting to close handle associated with file
+no: $fileno");
close $sockets{ $fileno };
delete $sockets{ $fileno };
}
}
Basically the while ( $Qclean->pending ) is not immediately triggerd (to close the socket in the main accept thread) because it is inside the while ( ... $sock->accept() ), and won't happen until another client connects, so the first client will just hang because it sees the socket on the server is still open.
In other words, client-A connects and sends request, gets response, but the server doesn't close the socket, so the client stays connected even though the server is done sending.
Then when client-B connects, Qclean is checked and sees the socket associated with client-A needs to be closed, so it goes ahead and closes it.
I'm stumped... Any thoughts/ideas on how to fix this?
Update:
I tried adding this early in my script:
SIG{PIPE}='IGNORE';
After re-adding the shutdown() line before close() in the handleConnection() sub to avoid the script blowing up because of SIGPIPE:
shutdown $socket, 2;
close $socket;
But then the client doesn't get the response (what is written on the socket by the server thread from the handleConnection() sub), just a connection drop :S
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.