From 78f15b09801f508a8db3b03cf40ab73c6d6b144d Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Fri, 15 Mar 2013 15:56:55 -0400 Subject: [PATCH] Multisession blocking repair The new socket blocking code for multisession failed to take into account that socket activity outside of the main block could lead to a deadlock situation. For example: * Check status of request A -> not complete * Check status of request B -> whatever * Request A may now be complete, since checking the status of any request affects all requests * Return to blocking loop because we think there is pending data, but in fact all data has already been pulled from the socket. The solution is for session_reap() to make a sweep and check for changes in requests that are now complete as a side-effect of checking for completed requests. Signed-off-by: Bill Erickson Signed-off-by: Galen Charlton --- src/perl/lib/OpenSRF/MultiSession.pm | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/perl/lib/OpenSRF/MultiSession.pm b/src/perl/lib/OpenSRF/MultiSession.pm index e196027..4b9a996 100644 --- a/src/perl/lib/OpenSRF/MultiSession.pm +++ b/src/perl/lib/OpenSRF/MultiSession.pm @@ -236,6 +236,20 @@ sub session_wait { } sub session_reap { + my $self = shift; + $self->_session_reap; + + # if any requests are marked complete as a side effect of + # _session_reap, re-run _session_reap. note that we check + # for completeness without touching the underlying socket + # (req->{complete} vs req->complete) to avoid additional + # unintended socket-touching side effects. + while (grep { $_->{req}->{complete} } @{$self->{running}}) { + $self->_session_reap; + } +} + +sub _session_reap { my $self = shift; my @done; -- 2.43.2