ut-proj / undertone

Making Music with Extempore, OSC, and SuperCollider in LFE/OTP
Apache License 2.0
57 stars 4 forks source link

Properly kill OS processes upon exit #88

Closed oubiwann closed 3 years ago

oubiwann commented 3 years ago

Right now, it seems that only calling (exit) from the REPL does go through the proper termination sequence (but only sendmidi is killed; receivemidi remains running). Issuing a SIGINT or SIGTERM don't seem to executing the full termination sequence at all, when run via rebar3 and the LFE REPL. Both OS processes for sendmidi and receivemidi remain running.

Tasks:

Related to #89

Part of epic #80

oubiwann commented 3 years ago

Take a look at these examples ... maybe something useful (from https://github.com/saleyn/erlexec/blob/master/src/exec.erl):

stop_and_wait(Pid, Timeout) when is_pid(Pid) ->
    gen_server:call(?MODULE, {port, {stop, Pid}}, Timeout),
    receive
    {'DOWN', _Ref, process, Pid, ExitStatus} -> ExitStatus
    after Timeout                            -> {error, timeout}
    end;
terminate(_Reason, State) ->
    try
        erlang:port_command(State#state.port, term_to_binary({0, {shutdown}})),
        case wait_port_exit(State#state.port) of
        0 -> ok;
        S -> error_logger:warning_msg("~w - exec process terminated (status: ~w)\n",
                [self(), S])
        end
    catch _:_ ->
        ok
    end.
wait_port_exit(Port) ->
    receive
    {Port,{exit_status,Status}} ->
        Status;
    _ ->
        wait_port_exit(Port)
    end.
notify_and_exit(true, Pid, OsPid, Reason) ->
    Pid ! {'DOWN', OsPid, process, self(), Reason},
    exit(Reason);
oubiwann commented 3 years ago

Also see How do you kill an OS process that was opened with open_port on a brutal_kill?. Highlight:

More from that thread.

oubiwann commented 3 years ago

Maybe just use https://github.com/saleyn/erlexec? Has all the features we need ...

Good docs: http://saleyn.github.io/erlexec/

oubiwann commented 3 years ago

Yeah, switching to erlexec fixed it!