Perform some clean up while killing a prolog process (may be a deamon on Unix) by kill -SIG PID Unix command.
on_signal/3 and at_halt/1 seem not working as expected.
I’m using: SWI-Prolog version:
SWI-Prolog version 8.5.3 for x86_64-darwin
I want the code to: run the :predicate registered by on_signal/3 or at_halt/1.
It is called while running
halt at top console. It did not get called while running
kill -quit PID from a OS terminal.
My code looks like this:
- use on_signal/3:
on_signal(usr1, _, ip_channel_close:ip_channel_kill),
print_message(error, format('signal caught: ~w', [SIG])).
kill -kill PID
- use at_halt/1:
print_message(error, format('signal caught', )).
kill -quit PID
Any help is greatly appreciated.
This works fine:
:- on_signal(term, _, terminate).
format('signal caught: ~w~n', [SIG]),
Save as e.g.,
swipl s.pl and kill using
kill -TERM PID
- Why use
ip_channel_close:? Is that due to the documentation as
:? This doc means the argument is module sensitive. One typically does not explicitly use Module:, but let the system fill this from the current context.
- You trap
SIGUSR1, but you kill using
kill -quit (not sure what that means anyway). Normal convention is to use SIGTERM for termination and
SIGHUP for reloading the server (e.g., call make/0, reload config, etc).
- There was a regression in some 8.5.x versions where signal handling stopped working.
- Note that if the application is multi-threaded the signal may be handled by any thread according to the POSIX specs. If you look at the library(http/http_unix_daemon) you’ll see the HTTP server runs in a thread and the main thread executes thread_get_message/1. The signal handler merely sends a thread signal to the main thread.
- see also library(main).
Thank you, Jan. Learned a lot from your remarks.
on_signal(usr1, _, ip_channel_close:ip_channel_kill) was
on_signal(quit, _, ip_channel_close:ip_channel_kill). A copy and paste error.
FYI: The quit signal was used because of the document says:
hup, term, abrt, quit
Causes normal Prolog cleanup (e.g., at_halt/1) before terminating the process with the same signal.
I thought at_halt/1 will be called transparently. Added
halt at the end of
ip_channel_kill and it worked properly.
Still a problem with deamon
Modified my code according to your code snippet and it worked in non-deamon process. But for the http_unix_deamon process, it still does not work. Looked at
main, http_unix_deamon and http_server, httpd and etc., I couldn’t figure out how to hookup
ip_channel_kill/1 to be called by
kill -TERM PID.
Further help is appreciated.
If you check out http_unix_daemon.pl you see it sets up signal handling, so your changes are overruled. See setup_signals/1 in that file. It calls halt(0) at the end, so using at_halt/1 should be enough to get something called as the server dies.
Jan, it works like a charm. You are great. Thank you again for all your help.