Skip to content

Commit

Permalink
Merge branch 'pan/active_once/OTP-10055' into maint
Browse files Browse the repository at this point in the history
* pan/active_once/OTP-10055:
  Remove race in gen_tcp_misc_SUITE:otp_9389
  gen_tcp: Make setopts(S,[{active,once}]) try a read
  • Loading branch information
bufflig committed May 4, 2012
2 parents c5d6ce6 + ee6fbc1 commit bb1734e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
23 changes: 21 additions & 2 deletions erts/emulator/drivers/common/inet_drv.c
Expand Up @@ -3124,6 +3124,7 @@ static int tcp_message(inet_descriptor* desc, const char* buf, int len)
int i = 0; int i = 0;


DEBUGF(("tcp_message(%ld): len = %d\r\n", (long)desc->port, len)); DEBUGF(("tcp_message(%ld): len = %d\r\n", (long)desc->port, len));
/* XXX fprintf(stderr,"tcp_message send.\r\n"); */


i = LOAD_ATOM(spec, i, am_tcp); i = LOAD_ATOM(spec, i, am_tcp);
i = LOAD_PORT(spec, i, desc->dport); i = LOAD_PORT(spec, i, desc->dport);
Expand Down Expand Up @@ -5426,6 +5427,7 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
if (IS_SCTP(desc)) if (IS_SCTP(desc))
return sctp_set_opts(desc, ptr, len); return sctp_set_opts(desc, ptr, len);
#endif #endif
/* XXX { int i; for(i=0;i<len;++i) fprintf(stderr,"0x%02X, ", (unsigned) ptr[i]); fprintf(stderr,"\r\n");} */


while(len >= 5) { while(len >= 5) {
opt = *ptr++; opt = *ptr++;
Expand Down Expand Up @@ -5755,10 +5757,16 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
if (desc->active != old_active) if (desc->active != old_active)
sock_select(desc, (FD_READ|FD_CLOSE), (desc->active>0)); sock_select(desc, (FD_READ|FD_CLOSE), (desc->active>0));


/* XXX: UDP sockets could also trigger immediate read here NIY */
if ((desc->stype==SOCK_STREAM) && desc->active) { if ((desc->stype==SOCK_STREAM) && desc->active) {
if (!old_active || (desc->htype != old_htype)) { if (!old_active || (desc->htype != old_htype)) {
/* passive => active change OR header type change in active mode */ /* passive => active change OR header type change in active mode */
return 1; /* Return > 1 if only active changed to INET_ONCE -> direct read if
header type is unchanged. */
/* XXX fprintf(stderr,"desc->htype == %d, old_htype == %d,
desc->active == %d, old_active == %d\r\n",(int)desc->htype,
(int) old_htype, (int) desc->active, (int) old_active );*/
return 1+(desc->htype == old_htype && desc->active == INET_ONCE);
} }
return 0; return 0;
} }
Expand Down Expand Up @@ -7592,17 +7600,27 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,


case INET_REQ_SETOPTS: { /* set options */ case INET_REQ_SETOPTS: { /* set options */
DEBUGF(("inet_ctl(%ld): SETOPTS\r\n", (long)desc->port)); DEBUGF(("inet_ctl(%ld): SETOPTS\r\n", (long)desc->port));
/* XXX fprintf(stderr,"inet_ctl(%ld): SETOPTS (len = %d)\r\n", (long)desc->port,(int) len); */
switch(inet_set_opts(desc, buf, len)) { switch(inet_set_opts(desc, buf, len)) {
case -1: case -1:
return ctl_error(EINVAL, rbuf, rsize); return ctl_error(EINVAL, rbuf, rsize);
case 0: case 0:
return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize); return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);
default: /* active/passive change!! */ case 1:
/* /*
* Let's hope that the descriptor really is a tcp_descriptor here. * Let's hope that the descriptor really is a tcp_descriptor here.
*/ */
/* fprintf(stderr,"Triggered tcp_deliver by setopt.\r\n"); */
tcp_deliver((tcp_descriptor *) desc, 0); tcp_deliver((tcp_descriptor *) desc, 0);
return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize); return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);
default:
/* fprintf(stderr,"Triggered tcp_recv by setopt.\r\n"); */
/*
* Same as above, but active changed to once w/o header type
* change, so try a read instead of just deliver.
*/
tcp_recv((tcp_descriptor *) desc, 0);
return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);
} }
} }


Expand Down Expand Up @@ -9196,6 +9214,7 @@ static int tcp_inet_input(tcp_descriptor* desc, HANDLE event)
#endif #endif
ASSERT(!INETP(desc)->is_ignored); ASSERT(!INETP(desc)->is_ignored);
DEBUGF(("tcp_inet_input(%ld) {s=%d\r\n", port, desc->inet.s)); DEBUGF(("tcp_inet_input(%ld) {s=%d\r\n", port, desc->inet.s));
/* XXX fprintf(stderr,"tcp_inet_input(%ld) {s=%d}\r\n",(long) desc->inet.port, desc->inet.s); */
if (desc->inet.state == INET_STATE_ACCEPTING) { if (desc->inet.state == INET_STATE_ACCEPTING) {
SOCKET s; SOCKET s;
unsigned int len; unsigned int len;
Expand Down
4 changes: 2 additions & 2 deletions lib/kernel/test/gen_tcp_misc_SUITE.erl
Expand Up @@ -2044,7 +2044,7 @@ send_timeout_active(Config) when is_list(Config) ->
?line {error,timeout} = ?line {error,timeout} =
Loop(fun() -> Loop(fun() ->
receive receive
{tcp, Sock, _Data} -> {tcp, _Sock, _Data} ->
inet:setopts(A, [{active, once}]), inet:setopts(A, [{active, once}]),
Res = gen_tcp:send(A,lists:duplicate(1000, $a)), Res = gen_tcp:send(A,lists:duplicate(1000, $a)),
%erlang:display(Res), %erlang:display(Res),
Expand Down Expand Up @@ -2536,7 +2536,7 @@ otp_8102_do(LSocket, PortNum, {Bin,PType}) ->
otp_9389(doc) -> ["Verify packet_size handles long HTTP header lines"]; otp_9389(doc) -> ["Verify packet_size handles long HTTP header lines"];
otp_9389(suite) -> []; otp_9389(suite) -> [];
otp_9389(Config) when is_list(Config) -> otp_9389(Config) when is_list(Config) ->
?line {ok, LS} = gen_tcp:listen(0, []), ?line {ok, LS} = gen_tcp:listen(0, [{active,false}]),
?line {ok, {_, PortNum}} = inet:sockname(LS), ?line {ok, {_, PortNum}} = inet:sockname(LS),
io:format("Listening on ~w with port number ~p\n", [LS, PortNum]), io:format("Listening on ~w with port number ~p\n", [LS, PortNum]),
OrigLinkHdr = "/" ++ string:chars($S, 8192), OrigLinkHdr = "/" ++ string:chars($S, 8192),
Expand Down

0 comments on commit bb1734e

Please sign in to comment.