moonlight-stream / moonlight-embedded

Gamestream client for embedded systems
https://github.com/moonlight-stream/moonlight-embedded/wiki
GNU General Public License v3.0
1.5k stars 325 forks source link

Move loop signal handling to main module and simplify code #735

Closed hhromic closed 5 years ago

hhromic commented 5 years ago

Description

Signal masking (sigprocmask) must be done before any threads are created for the masking to be inherited by all threads. Otherwise, signals are captured by unmasked threads and the default system handlers are used instead.

Currently, for example if a SIGTERM signal is sent to Moonlight while in a streaming session, the program completely terminates without any de-initialisataion, i.e. the loop signal handler is not called and the event loop is abruptly finished (system default signal handler is called):

Starting control stream...done
Starting video stream...done
Starting audio stream...done
Starting input stream...done
(..signal sent here..)
Terminated

Therefore, move the initialisation of signals and handlers to the main module where it can be done before any other threads are created, e.g. platform, video and connection threads.

With this change, when sending the example SIGTERM signal, now the loop signal handler is always properly called and Moonlight gracefully finishes the session:

Starting control stream...done
Starting video stream...done
Starting audio stream...done
Starting input stream...done
(..signal sent here..)
Stopping input stream...done
Stopping audio stream...ENet wait interrupted
Control stream connection failed
Loss Stats: Transaction failed: 11
done
Stopping video stream...done
Stopping control stream...done
Cleaning up input stream...done
Cleaning up audio stream...done
Cleaning up video stream...done
Cleaning up control stream...done
Cleaning up platform...done

Also, this allows to simplify the loop module code.

Purpose

Fix signal handling in the Moonlight event loop.

irtimmer commented 5 years ago

The main reason the signal masking code is in loop.c is because it's optional, as SDL will do its own signal masking (although I'm unsure if it's currently done before or after the thread creation). Therefore I've fixed the issue without moving the code to main.c and excluding the code cleanups with commit d7ac8654e58f5a5f309b8043f82a69b92062863d

hhromic commented 5 years ago

The main reason the signal masking code is in loop.c is because it's optional, as SDL will do its own signal masking

Ah didn't think about SDL, you are right. Your commit is better in that case! Thanks for fixing the issue, appreciated.