[erlang-questions] flushing IO

Claes Wikstrom klacke@REDACTED
Tue May 13 15:05:36 CEST 2008


One thing that is sorely missing from Erlang (still) is a
proper way to stop the node and flushing all I/O

init:stop() doesn't ensure that all IO sent through
for example io:format() is indeed flushed. We've had
to add the following incredibly ugly code.


stop(Code) ->
     %% Ugly stuff to make sure ouput is flushed
     User = whereis(user),
     lists:foreach(fun(Port) ->
                           case erlang:port_info(Port, connected) of
                               {connected, User} ->
                                   erlang:port_connect(Port, self()),
                                   Port ! {self(), close},
                                   receive
                                       {Port, closed} -> ok
                                   after 1000 -> ok
                                   end,
                                   erlang:halt(Code);
                               _ -> ok
                           end
                   end, erlang:ports()),
     timer:sleep(1000),
     erlang:halt(Code).


Moreover, ponder the following:

# time erl -noshell -s erlang halt
erl -noshell -s erlang halt  0.09s user 0.01s system 93% cpu 0.111 total
# time erl -noshell -s init stop
erl -noshell -s init stop  0.10s user 0.01s system 10% cpu 1.119 total


I've for quite some time been irritated with init:stop() being slow,
The only reason it appears to flush IO is that somewhere - deep down -
there is some code sleeping for 1 sec.  Buggy. Shutting down should
be more controlled. Not that I have any patches to contribute here and
even if I did I doubt that they would be accepted. Nevertheless, I just
wanted to:

a) Post code that ensures that all IO is flushed.
b) Report the bug.


In init.erl there is code

kill_all_ports(Heart,[P|Ps]) ->
     case erlang:port_info(P,connected) of
	{connected,Heart} ->
	    kill_all_ports(Heart,Ps);
	_ ->
	    case erlang:port_info(P, name) of
		{name, "async"} ->
		    kill_all_ports(Heart,Ps);
		_ ->
		    exit(P,kill),
		    kill_all_ports(Heart,Ps)
	    end
     end;
kill_all_ports(_,_) ->
     ok.


exit(Port, kill) doesn't flush the port IO whereas

                       erlang:port_connect(Port, self()),
                       Port ! {self(), close},
                       receive
                            {Port, closed} -> ok
                       .....

does.



/klacke






More information about the erlang-questions mailing list