mirror of https://github.com/OpenKMIP/PyKMIP.git
Merge pull request #241 from OpenKMIP/bug/fix-server-interrupt-handling
Fixes a bug with socket interrupt handling under Python3.5
This commit is contained in:
commit
778c01893c
|
@ -13,7 +13,6 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import errno
|
|
||||||
import logging
|
import logging
|
||||||
import logging.handlers as handlers
|
import logging.handlers as handlers
|
||||||
import optparse
|
import optparse
|
||||||
|
@ -287,6 +286,13 @@ class KmipServer(object):
|
||||||
def _signal_handler(signal_number, stack_frame):
|
def _signal_handler(signal_number, stack_frame):
|
||||||
self._is_serving = False
|
self._is_serving = False
|
||||||
|
|
||||||
|
# Python3.5+ silently ignores SIGINT and retries system calls if
|
||||||
|
# the signal handler does not raise an exception. Explicitly
|
||||||
|
# detect SIGINT and raise a KeyboardInterrupt exception to regain
|
||||||
|
# old functionality.
|
||||||
|
if signal_number == signal.SIGINT:
|
||||||
|
raise KeyboardInterrupt("SIGINT received")
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, _signal_handler)
|
signal.signal(signal.SIGINT, _signal_handler)
|
||||||
signal.signal(signal.SIGTERM, _signal_handler)
|
signal.signal(signal.SIGTERM, _signal_handler)
|
||||||
|
|
||||||
|
@ -296,14 +302,14 @@ class KmipServer(object):
|
||||||
try:
|
try:
|
||||||
connection, address = self._socket.accept()
|
connection, address = self._socket.accept()
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
if e.errno == errno.EINTR:
|
|
||||||
self._logger.warning("Interrupting connection service.")
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self._logger.warning(
|
self._logger.warning(
|
||||||
"Error detected while establishing new connection."
|
"Error detected while establishing new connection."
|
||||||
)
|
)
|
||||||
self._logger.exception(e)
|
self._logger.exception(e)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
self._logger.warning("Interrupting connection service.")
|
||||||
|
self._is_serving = False
|
||||||
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._logger.warning(
|
self._logger.warning(
|
||||||
"Error detected while establishing new connection."
|
"Error detected while establishing new connection."
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import errno
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -363,8 +362,7 @@ class TestKmipServer(testtools.TestCase):
|
||||||
s._socket = mock.MagicMock()
|
s._socket = mock.MagicMock()
|
||||||
s._setup_connection_handler = mock.MagicMock()
|
s._setup_connection_handler = mock.MagicMock()
|
||||||
|
|
||||||
expected_error = socket.error()
|
expected_error = KeyboardInterrupt
|
||||||
expected_error.errno = errno.EINTR
|
|
||||||
|
|
||||||
# Test the expected behavior for a normal server/interrupt sequence
|
# Test the expected behavior for a normal server/interrupt sequence
|
||||||
s._socket.accept = mock.MagicMock(
|
s._socket.accept = mock.MagicMock(
|
||||||
|
@ -418,7 +416,13 @@ class TestKmipServer(testtools.TestCase):
|
||||||
# Test the signal handler for each expected signal
|
# Test the signal handler for each expected signal
|
||||||
s._is_serving = True
|
s._is_serving = True
|
||||||
handler = signal.getsignal(signal.SIGINT)
|
handler = signal.getsignal(signal.SIGINT)
|
||||||
handler(None, None)
|
args = (signal.SIGINT, None)
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
KeyboardInterrupt,
|
||||||
|
"SIGINT received",
|
||||||
|
handler,
|
||||||
|
*args
|
||||||
|
)
|
||||||
self.assertFalse(s._is_serving)
|
self.assertFalse(s._is_serving)
|
||||||
|
|
||||||
s._is_serving = True
|
s._is_serving = True
|
||||||
|
|
Loading…
Reference in New Issue