<div dir="ltr"><div><div>I believe the race condition occurring is that the gen_tcp port will exit after it sends a {tcp_closed, Socket} message when in active mode. When calling a gen_tcp function the module for the Socket (Erlang port) is looked up using a BIF (for ipv4 and ipv6 are different modules internally). If the port doesn't exist when the lookup occurs then you get {error, closed}. Otherwise the module is returned and that module is used to communicate with Socket (Erlang port). It is possible for the port to exit in between the lookup of the module and the actual call. This situation leads to {error, einval} as that is the error returned by the lower level inet port calls. You can see this occur when using inet:setopts/2 as the module isn't looked up (IIRC) and {error, einval} is always returned on a "dead" Erlang port.<br><br></div>It is possible to stop the gen_tcp socket exiting on {tcp_closed, Socket} by using the {exit_on_close, false} inet option. However then you will need to call gen_tcp:close(Socket) if the controlling process does not exit when the connection closes.<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 30 June 2016 at 14:58, Jesper Louis Andersen <span dir="ltr"><<a href="mailto:jesper.louis.andersen@gmail.com" target="_blank">jesper.louis.andersen@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class=""><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 30, 2016 at 10:58 AM, Magnus Ottenklinger <span dir="ltr"><<a href="mailto:magnus.ottenklinger@entelios.com" target="_blank">magnus.ottenklinger@entelios.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We stumbled over a peculiarity in the usage of ports in a TCP connection (active mode). Specifically, we encountered `einval` when writing to a socket which was closed just before. Our expectation was that the resulting error should be `{error,closed}`. The following module reproduces this on my machine (OTP 19.0). I ran the test module with `erlc test.erl && erl -s test run -noshell` as well as with `erl -smp disable +A 0 -s test run -noshell`. Both executions triggered `einval`.</blockquote></div><br></div></span><div class="gmail_extra">Knowing what operating system it is could help. Low level TCP isn't entirely the same thing in its response codes, even though POSIX exists. There are some things down here which are up to "interpretation" for some levels of interpretation.<br><br></div><div class="gmail_extra">It does, from your failing program, look like it is a race however. The question is if anything can be done about it.<span class="HOEnZb"><font color="#888888"><br><br></font></span></div><span class="HOEnZb"><font color="#888888"><div class="gmail_extra"><br clear="all"><br>-- <br><div data-smartmail="gmail_signature">J.</div>
</div></font></span></div>
<br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></blockquote></div><br></div>