Restore correct signal handling in Python3
The patch2ee3894f49
broke the original fixcad75e4e13
that ensured eventlet could be interrupted while sleeping after PEP475 was implemented in Python 3.5. Eventlet monkey-patches the signal module with its own version, so we have to look up the original module to determine whether the underlying OS actually supports the poll() function. Change-Id: Ia712c9a83d8081bf0b5e6fe36f169f9028aae3dc Closes-Bug: #1803731 Related-Bug: #1788022 Related-Bug: #1705047
This commit is contained in:
parent
b85d9353fb
commit
159ef2e1d2
|
@ -28,7 +28,6 @@ import io
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import select
|
|
||||||
import signal
|
import signal
|
||||||
import six
|
import six
|
||||||
import sys
|
import sys
|
||||||
|
@ -204,8 +203,9 @@ class SignalHandler(object):
|
||||||
For Python 3.5 and later, deal with the changes in PEP 475 that prevent
|
For Python 3.5 and later, deal with the changes in PEP 475 that prevent
|
||||||
a signal from interrupting eventlet's call to poll() or sleep().
|
a signal from interrupting eventlet's call to poll() or sleep().
|
||||||
"""
|
"""
|
||||||
|
select_module = eventlet.patcher.original('select')
|
||||||
self.__force_interrupt_on_signal = (sys.version_info >= (3, 5) and
|
self.__force_interrupt_on_signal = (sys.version_info >= (3, 5) and
|
||||||
hasattr(select, 'poll'))
|
hasattr(select_module, 'poll'))
|
||||||
|
|
||||||
if self.__force_interrupt_on_signal:
|
if self.__force_interrupt_on_signal:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -478,15 +478,28 @@ class ProcessLauncherTest(base.ServiceBaseTestCase):
|
||||||
signal_handler.clear()
|
signal_handler.clear()
|
||||||
|
|
||||||
@mock.patch('sys.version_info', (3, 5))
|
@mock.patch('sys.version_info', (3, 5))
|
||||||
@mock.patch.object(service, 'select', spec=[])
|
def test_setup_signal_interruption_no_select_poll(self):
|
||||||
def test_setup_signal_interruption_no_select_poll(self, mock_select):
|
# NOTE(claudiub): SignalHandler is a singleton, which means that it
|
||||||
|
# might already be initialized. We need to clear to clear the cache
|
||||||
|
# in order to prevent race conditions between tests.
|
||||||
|
service.SignalHandler.__class__._instances.clear()
|
||||||
|
with mock.patch('eventlet.patcher.original',
|
||||||
|
return_value=object()) as get_original:
|
||||||
|
signal_handler = service.SignalHandler()
|
||||||
|
get_original.assert_called_with('select')
|
||||||
|
self.addCleanup(service.SignalHandler.__class__._instances.clear)
|
||||||
|
self.assertFalse(
|
||||||
|
signal_handler._SignalHandler__force_interrupt_on_signal)
|
||||||
|
|
||||||
|
@mock.patch('sys.version_info', (3, 5))
|
||||||
|
def test_setup_signal_interruption_select_poll(self):
|
||||||
# NOTE(claudiub): SignalHandler is a singleton, which means that it
|
# NOTE(claudiub): SignalHandler is a singleton, which means that it
|
||||||
# might already be initialized. We need to clear to clear the cache
|
# might already be initialized. We need to clear to clear the cache
|
||||||
# in order to prevent race conditions between tests.
|
# in order to prevent race conditions between tests.
|
||||||
service.SignalHandler.__class__._instances.clear()
|
service.SignalHandler.__class__._instances.clear()
|
||||||
signal_handler = service.SignalHandler()
|
signal_handler = service.SignalHandler()
|
||||||
self.addCleanup(service.SignalHandler.__class__._instances.clear)
|
self.addCleanup(service.SignalHandler.__class__._instances.clear)
|
||||||
self.assertFalse(
|
self.assertTrue(
|
||||||
signal_handler._SignalHandler__force_interrupt_on_signal)
|
signal_handler._SignalHandler__force_interrupt_on_signal)
|
||||||
|
|
||||||
@mock.patch('signal.alarm')
|
@mock.patch('signal.alarm')
|
||||||
|
|
Loading…
Reference in New Issue