libretro / RetroArch

Cross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.
http://www.libretro.com
GNU General Public License v3.0
9.79k stars 1.78k forks source link

SIGTERM implementation has a less good behavior than hotkey "quit" feature #15717

Open schmurtzm opened 9 months ago

schmurtzm commented 9 months ago

Description

Normally when you make a kill PID_of_Retroarch it should exit gracefully/cleanly retroarch (letting it saving RAM, etc. properly). In most situation sigterm works properly but not with many games of Mame2003+ (see this Mame2003+ core issue for details) where many games doesn't allow to close Retroarch with a sigterm.

However using "quit" hotkey works properly in all the cases with Mame2003+. It make me think that the Retroarch SIGTERM implementation should copy the behavior of this "quit" hotkey to allow to quit properly Retroarch when it's asked by the system.

Expected behavior

Be able to quit properly Retroarch with a sigterm whatever the core or the game used. It will allow to ask to retroarch to close from external program without having to manipulate the Retroarch menu: useful on many handhelds for example to quit RA with a long press of a button.

Actual behavior

A sigterm When playing "1942" for example on Mame 2003+ will not close Retroarch.

Steps to reproduce the bug

Start Retroarch with mame2003-plus and run 1942, send a pkill retroarch command. Normally Retroarch should exit and make a save state (if the "Auto Save State" option is enabled) but here nothing happens.

Example of result with After Burner :

/ # pkill retroarch
/ # SDL_PrivateQuit          -> nothing happens, the game still runnning after that.

Other observations

On mame 2003 +, sigterm doesn't work with:

  • 1942,1943
  • After Burner
  • arknoid2
  • shinobi
  • superman
  • xmen

But it works with:

  • Act-Fancer: Cybernetick Hyper Weapon
  • aerofgt
  • batman
  • Elevator Action Returns
  • tmnt

So it seems that the behavior of sigterm is different depending the game (different behaviors from different mame game drivers ?)

Version/Commit

Environment information

zoltanvb commented 9 months ago

Bit weird. One sigterm should not do a lot, based on this code: https://github.com/libretro/RetroArch/blob/041ae3010332da1155d1ac6d6368dd05d2c3003e/frontend/drivers/platform_unix.c#L2491 It could work a bit better.

schmurtzm commented 9 months ago

Additional info :

The QUIT command from RA network-control-interface is working properly : it exits arcade and it makes the save state. So it will be a workaround as long as kill command is not working properly.


The hotkey QUIT is working and seems to be managed here : https://github.com/libretro/RetroArch/blob/041ae3010332da1155d1ac6d6368dd05d2c3003e/runloop.h#L77

The QUIT from the network control interface is managed here : https://github.com/libretro/RetroArch/blob/041ae3010332da1155d1ac6d6368dd05d2c3003e/command.h#L450

Kill command / Sigterm seems to be managed in platform_unix.c: https://github.com/libretro/RetroArch/blob/041ae3010332da1155d1ac6d6368dd05d2c3003e/frontend/drivers/platform_unix.c#L2484

sonninnos commented 9 months ago

Wouldn't it make sense to do main_exit(NULL); instead of exit(1); here: if (unix_sighandler_quit == 2) exit(1);

schmurtzm commented 9 months ago

Just tried, no it doesn't improve the behavior of kill command. :/

sonninnos commented 9 months ago

Dang. What is the value of unix_sighandler_quit on that moment then, and does it even hit that function?

zoltanvb commented 9 months ago

I need to correct myself, after one signal the value is just passed to frontend_driver_get_signal_handler_state() and is queried from several places, usually in the graphics context drivers, which should take care of the controlled shutdown. Which driver are you using? gl, glcore, vulkan? Also, x11 or wayland?

schmurtzm commented 9 months ago

Dang. What is the value of unix_sighandler_quit on that moment then, and does it even hit that function?

I don't have a debugger on my platform 😅

Which driver are you using? gl, glcore, vulkan

I'm using a custom one based on SDL for Miyoo Mini

sonninnos commented 9 months ago

No debugger needed when printf exists.

zoltanvb commented 9 months ago

And what is the context driver? (It can be seen from Information / System Information)

zoltanvb commented 9 months ago

Just taking a guess, it may be this one: https://github.com/libretro/RetroArch/blob/712b9350a5c2b1b9129d939a2ae622093dfabd04/gfx/drivers_context/sdl_gl_ctx.c#L317 Other context drivers usually query frontend_driver_get_signal_handler_state() and set value of quit* accordingly, while this context driver relies on SDL events only.

schmurtzm commented 9 months ago

Yes the context driver is indeed SDL 1.2 And when I do a pkill retroarch I just have this message : SDL_PrivateQuit (and then RA doesn't end) Any test to do to improve this behavior ?

zoltanvb commented 9 months ago

SDL_PrivateQuit seems to be an internal SDL function. It should raise an SDL event, but maybe it does not happen or it has some different type. If I read SDL 1.2 source right, that is... If you can build RA for this setup, you can try adding RARCH_LOG() loggings to that sdl_ctx_check_window() function, to see if there is any SDL event that is seen here when kill is received. Something like: RARCH_LOG("SDL event received: %d\n",event.type); just before switch (event.type).