Skip to content

Commit

Permalink
Killing the monitoring thread should restore the greenlet trace funct…
Browse files Browse the repository at this point in the history
…ion.
  • Loading branch information
jamadden committed Mar 20, 2018
1 parent fcfc930 commit 6f9e51f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
19 changes: 13 additions & 6 deletions src/gevent/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ class PeriodicMonitoringThread(object):

# The trace function that was previously installed,
# if any.
previous_trace_function = staticmethod(lambda _event, _args: None)
previous_trace_function = None

# The absolute minimum we will sleep, regardless of
# what particular monitoring functions want to say.
Expand All @@ -485,7 +485,7 @@ def __init__(self, hub):
# the trace function is threadlocal
assert get_thread_ident() == hub.thread_ident
prev_trace = settrace(self.greenlet_trace)
self.previous_trace_function = prev_trace or self.previous_trace_function
self.previous_trace_function = prev_trace

# Create the actual monitoring thread. This is effectively a "daemon"
# thread.
Expand All @@ -500,7 +500,8 @@ def greenlet_trace(self, event, args):
self._active_greenlet = args[1]
else:
self._active_greenlet = None
self.previous_trace_function(event, args)
if self.previous_trace_function is not None:
self.previous_trace_function(event, args)

def monitoring_functions(self):
# Return a list of tuples: [(function, period)]
Expand All @@ -521,6 +522,8 @@ def calculate_sleep_time(self, monitoring_functions):
def kill(self):
# Stop this monitoring thread from running.
self.should_run = False
# Uninstall our tracing hook
settrace(self.previous_trace_function)

def __call__(self):
# The function that runs in the monitoring thread.
Expand All @@ -539,9 +542,13 @@ def __call__(self):
# Make sure the hub is still around, and still active,
# and keep it around while we are here.
hub = self._hub_wref()
if hub and self.should_run:
for f, _ in functions:
f(hub)
if not hub:
self.kill()

if self.should_run:
for f, period in functions:
if period:
f(hub)
except SystemExit:
pass
except: # pylint:disable=bare-except
Expand Down
10 changes: 9 additions & 1 deletion src/greentest/test__hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,20 @@ def monitor_cond(_hub):
before_funs = monitor._additional_monitoring_functions
monitor.add_monitoring_function(
monitor_cond,
0)
0.01)

cond.wait()
cond.release()
monitor._additional_monitoring_functions = before_funs

@greentest.ignores_leakcheck
def test_kill_removes_trace(self):
from greenlet import gettrace
hub = get_hub()
hub.start_periodic_monitoring_thread()
self.assertIsNotNone(gettrace())
hub.periodic_monitoring_thread.kill()
self.assertIsNone(gettrace())

@greentest.ignores_leakcheck
def test_blocking_this_thread(self):
Expand Down

0 comments on commit 6f9e51f

Please sign in to comment.