taurus-org / taurus

Moved to https://gitlab.com/taurus-org/taurus
http://taurus-scada.org
43 stars 46 forks source link

Thread deadlock in TaurusPollingTimer #1178

Open cpascual opened 3 years ago

cpascual commented 3 years ago

I suspect that some of the issues that we are experimenting in the CI may be related to a deadlock in TaurusPollingTimer (thanks @reszelaz for helping with the debugging)

I can reproduce it with the following snippet:

from taurus.core import TaurusPollingTimer
import taurus
import sys

a = taurus.Attribute("eval:1")

pt = TaurusPollingTimer(period=10)
for i in range(100):
    pt.addAttribute(a)
    print(i, end=" ")
    sys.stdout.flush()
    pt.removeAttribute(a)

And here is the backtrace when I use CTRL+C to interrupt it after it got in a deadlock:

$ python /home/cpascual/.config/JetBrains/PyCharmCE2020.2/scratches/scratch_153.py                        (taurus) 
0 1 2 3 4 5 6 7 8 9 ^CTraceback (most recent call last):
TimerLoop 10   WARNING  2021-03-01 17:55:56,591 TaurusPollingTimer[10].Timer on _pollAttributes: loop function took more than loop interval (0.01s)
  File "/home/cpascual/.config/JetBrains/PyCharmCE2020.2/scratches/scratch_153.py", line 12, in <module>
    pt.removeAttribute(a)
  File "/home/cpascual/src/taurus/lib/taurus/core/tauruspollingtimer.py", line 131, in removeAttribute
    self.stop(sync=True)
  File "/home/cpascual/src/taurus/lib/taurus/core/tauruspollingtimer.py", line 63, in stop
    self.timer.stop(sync=sync)
  File "/home/cpascual/src/taurus/lib/taurus/core/util/timer.py", line 86, in stop
    self.__thread.join()
  File "/home/cpascual/miniconda/envs/taurus/lib/python3.9/threading.py", line 1033, in join
    self._wait_for_tstate_lock()
  File "/home/cpascual/miniconda/envs/taurus/lib/python3.9/threading.py", line 1049, in _wait_for_tstate_lock
    elif lock.acquire(block, timeout):
KeyboardInterrupt
cpascual commented 3 years ago

This deadlock was almost certainly introduced in PR #1002