2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-08-24 12:10:25 +00:00

Reorganize UDP <-> SSL rework

Because SSL actually was relying upon accept() to hold indefininetly,
it would hang up the UDP worker indefinitely, blocking requests.
Fix this by driving the loop iteration through select() rather than
accept() and iterating through each file handle only when select()
says they are ready.
This commit is contained in:
Jarrod Johnson
2015-05-27 10:23:37 -04:00
parent 6726d4e208
commit 49c809e031

View File

@@ -1099,6 +1099,7 @@ while (not $listener and $retry) {
}
my $listenwatcher = IO::Select->new($listener);
my $udpwatcher = IO::Select->new($udpctl);
my $bothwatcher = IO::Select->new($udpctl, $listener);
unless ($listener) {
kill 2, $pid_UDP;
@@ -1130,6 +1131,17 @@ my $tconn;
my $sslfudgefactor = 0;
until ($quit) {
$SIG{CHLD} = \&ssl_reaper; #set here to ensure that signal handler is not corrupted during loop
while ($udpwatcher->can_read(0)) { # take an intermission to broker some state requests from udp traffic control
eval {
my $msg = fd_retrieve($udpctl);
if ($msg->{req} eq 'get_client_count') {
store_fd({'clientfudge'=>$sslfudgefactor, 'sslclientcount' => $sslclients}, $udpctl);
} elsif ($msg->{req} eq 'set_fudge_factor') {
$sslfudgefactor = $msg->{fudge};
store_fd({'clientfudge'=>$sslfudgefactor, 'sslclientcount' => $sslclients}, $udpctl);
}
};
}
if (@pendingconnections) {
while ($listenwatcher->can_read(0)) { #grab everything we can, but don't spend any time waiting for more
$tconn = $listener->accept;
@@ -1137,21 +1149,16 @@ until ($quit) {
push @pendingconnections,$tconn;
}
} else {
$bothwatcher->can_read(30);
if (not $listenwatcher->can_read(0)) { # check for udpctl messages since
# we have no listen to hear
next;
}
$tconn = $listener->accept; #we have no connections pending, no rush, just wait until the next connection attempt comes in
unless ($tconn) { next; } #sometimes we get 'undef', in which case carry on with our lives...
push @pendingconnections,$tconn;
}
unless (scalar @pendingconnections) { next; } #if for some reason we landed here without any accepted connections, carry on..
while ($udpwatcher->can_read(0)) { # take an intermission to broker some state requests from udp traffic control
eval {
my $msg = fd_retrieve($udpctl);
if ($msg->{req} eq 'get_client_count') {
store_fd({'clientfudge'=>$sslfudgefactor, 'sslclientcount' => $sslclients});
} elsif ($msg->{req} eq 'set_fudge_factor') {
$sslfudgefactor = $msg->{fudge};
}
};
}
if ($sslclients > $maxsslclients) { #we have enough children, wait for some to exit before spawning more
$listenwatcher->can_read(0.1); #when next connection tries to come in or a tenth of a second, whichever comes first
next; #just keep pulling things off listen queue onto our own