Closed joerick closed 8 years ago
Pause happens here:
(between l3
and l4
)
If running in a console, can be fixed by hitting ^C... strange. Perhaps the pause is in pygame or SDL?
Idea: Does SDL/pygame set a custom signal handler for SIGTERM? Perhaps it does, and if the app is locked, then it never does some essential cleanup and that hoses the system?
SDL does set a handler for SIGTERM and converts it to a SDL_QUIT event.
So that is caught in the standard event loop, when a tingbot app is responsive. But, if the app is caught in spin-lock or just busy somewhere for a few seconds, tbprocessd gets bored waiting for the app to quit and sends SIGKILL.
It looks like there's some vital cleanup that SDL must do before exiting - if this isn't done, we get to the problem that we've seen.
The following signal handler seems to fix the problem in a trivial test. Without the signal handler, the system locks.
def quit_handler(sig, frame):
import pygame, sys
pygame.quit()
sys.exit(14)
signal.signal(signal.SIGTERM, quit_handler)
Full app code here:
import tingbot
from tingbot import *
import signal
# setup code here
screen.fill(color='black')
screen.text('Hello world!')
def quit_handler(sig, frame):
import pygame, sys
pygame.quit()
sys.exit(14)
signal.signal(signal.SIGTERM, quit_handler)
def loop():
# drawing code here
screen.fill(color='black')
screen.text('Hello world!')
while True:
pass
# run the app
tingbot.run(loop)
SDL hangs while trying to do something to do with virtual terminals - if run with strace
the line...
select(6, [5], NULL, NULL, {1, 0}) = 1 (in [5], left {0, 999989})
read(5, "\372", 1) = 1
select(6, [5], NULL, NULL, {1, 0}) = 1 (in [5], left {0, 999992})
read(5, "\3", 1) = 1
rt_sigaction(SIGINT, NULL, {0x1275a8, [], SA_RESTORER, 0x76d3c180}, 8) = 0
rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, NULL, {0x1275a8, [], SA_RESTORER, 0x76d3c180}, 8) = 0
rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {0x769ea49c, [], SA_RESTORER, 0x76d3c180}, NULL, 8) = 0
ioctl(4, VT_GETSTATE, 0x7ea580d8) = 0
ioctl(4, VT_ACTIVATE, 0x3) = 0
ioctl(4, VT_WAITACTIVE
...and it hangs there. It's part of the fbcon code, in function FB_EnterGraphicsMode.
Fixed in tingbot/tingbot-python@e7059b8b63f50b59069542651d684c17d4e1d671
If this remains a persistent problem, this code fixes a broken terminal:
https://gist.github.com/joerick/9e2d244f456c2431619e7063eda62e1d
May be SDL/pygame or tbprocessd related. Not sure yet, needs debugging.