aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2010-02-08 15:56:55 +0000
committerErlang/OTP <[email protected]>2010-02-08 15:56:55 +0000
commit51bb4c6ae1e4d61304aee5b4bf77279d838da84a (patch)
tree8ffeb120513b2e1bc4de8e32560d3956e67cfd82 /lib/kernel/src
parent52f763526c95a7eb12fcfbdf07bb1216a1b756b4 (diff)
parent827bb85bafd96ec3037c849ea42878e4f581d22f (diff)
downloadotp-51bb4c6ae1e4d61304aee5b4bf77279d838da84a.tar.gz
otp-51bb4c6ae1e4d61304aee5b4bf77279d838da84a.tar.bz2
otp-51bb4c6ae1e4d61304aee5b4bf77279d838da84a.zip
Merge branch 'sc/sctp-connect-nowait' into ccase/r13b04_dev
* sc/sctp-connect-nowait: Implement a non-blocking SCTP connect OTP-8414 There are new gen_sctp:connect_init/* functions that initiate an SCTP connection without blocking for the result. The result is delivered asynchronously as an sctp_assoc_change event. (Thanks to Simon Cornish.)
Diffstat (limited to 'lib/kernel/src')
-rw-r--r--lib/kernel/src/gen_sctp.erl46
-rw-r--r--lib/kernel/src/inet_sctp.erl30
2 files changed, 53 insertions, 23 deletions
diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl
index fcd1d1564a..5a31e3976f 100644
--- a/lib/kernel/src/gen_sctp.erl
+++ b/lib/kernel/src/gen_sctp.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -27,7 +27,7 @@
-include("inet_sctp.hrl").
-export([open/0,open/1,open/2,close/1]).
--export([listen/2,connect/4,connect/5]).
+-export([listen/2,connect/4,connect/5,connect_init/4,connect_init/5]).
-export([eof/2,abort/2]).
-export([send/3,send/4,recv/1,recv/2]).
-export([error_string/1]).
@@ -80,7 +80,26 @@ listen(S, Flag) ->
connect(S, Addr, Port, Opts) ->
connect(S, Addr, Port, Opts, infinity).
-connect(S, Addr, Port, Opts, Timeout) when is_port(S), is_list(Opts) ->
+connect(S, Addr, Port, Opts, Timeout) ->
+ case do_connect(S, Addr, Port, Opts, Timeout, true) of
+ badarg ->
+ erlang:error(badarg, [S,Addr,Port,Opts,Timeout]);
+ Result ->
+ Result
+ end.
+
+connect_init(S, Addr, Port, Opts) ->
+ connect_init(S, Addr, Port, Opts, infinity).
+
+connect_init(S, Addr, Port, Opts, Timeout) ->
+ case do_connect(S, Addr, Port, Opts, Timeout, false) of
+ badarg ->
+ erlang:error(badarg, [S,Addr,Port,Opts,Timeout]);
+ Result ->
+ Result
+ end.
+
+do_connect(S, Addr, Port, Opts, Timeout, ConnWait) when is_port(S), is_list(Opts) ->
case inet_db:lookup_socket(S) of
{ok,Mod} ->
case Mod:getserv(Port) of
@@ -89,21 +108,26 @@ connect(S, Addr, Port, Opts, Timeout) when is_port(S), is_list(Opts) ->
Timer ->
try Mod:getaddr(Addr, Timer) of
{ok,IP} ->
- Mod:connect(S, IP, Port, Opts, Timer);
+ ConnectTimer = if ConnWait == false ->
+ nowait;
+ true ->
+ Timer
+ end,
+ Mod:connect(S, IP, Port, Opts, ConnectTimer);
Error -> Error
after
inet:stop_timer(Timer)
end
catch
error:badarg ->
- erlang:error(badarg, [S,Addr,Port,Opts,Timeout])
+ badarg
end;
Error -> Error
end;
Error -> Error
end;
-connect(S, Addr, Port, Opts, Timeout) ->
- erlang:error(badarg, [S,Addr,Port,Opts,Timeout]).
+do_connect(_S, _Addr, _Port, _Opts, _Timeout, _ConnWait) ->
+ badarg.
diff --git a/lib/kernel/src/inet_sctp.erl b/lib/kernel/src/inet_sctp.erl
index 30c0e85dd9..795bf83807 100644
--- a/lib/kernel/src/inet_sctp.erl
+++ b/lib/kernel/src/inet_sctp.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% SCTP protocol contribution by Leonid Timochouk and Serge Aleynikov.
@@ -64,16 +64,22 @@ close(S) ->
listen(S, Flag) ->
prim_inet:listen(S, Flag).
+%% A non-blocking connect is implemented when the initial call is to
+%% gen_sctp:connect_init which passes the value nowait as the Timer
connect(S, Addr, Port, Opts, Timer) ->
case prim_inet:chgopts(S, Opts) of
ok ->
case prim_inet:getopt(S, active) of
{ok,Active} ->
- Timeout = inet:timeout(Timer),
+ Timeout = if Timer =:= nowait ->
+ infinity; %% don't start driver timer in inet_drv
+ true ->
+ inet:timeout(Timer)
+ end,
case prim_inet:connect(S, Addr, Port, Timeout) of
- ok ->
+ ok when Timer =/= nowait ->
connect_get_assoc(S, Addr, Port, Active, Timer);
- Err1 -> Err1
+ OkOrErr1 -> OkOrErr1
end;
Err2 -> Err2
end;
@@ -89,10 +95,10 @@ connect(S, Addr, Port, Opts, Timer) ->
%% connect_get_assoc/5 below mistakes it for an invalid response
%% for a socket in {active,false} or {active,once} modes.
%%
-%% In {active,true} mode it probably gets right, but it is
-%% a blocking connect that is implemented even for {active,true},
-%% and that may be a shortcoming. A non-blocking connect
-%% would be nice to have.
+%% In {active,true} mode the window of time for the race is smaller,
+%% but it is possible and also it is a blocking connect that is
+%% implemented even for {active,true}, and that may be a
+%% shortcoming.
connect_get_assoc(S, Addr, Port, false, Timer) ->
case recv(S, inet:timeout(Timer)) of