diff options
author | Jeroen Koops <[email protected]> | 2011-02-08 22:53:55 +0100 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2011-03-07 13:50:07 +0100 |
commit | c034b8ce819cfe1171720499387815ae8dc84bc9 (patch) | |
tree | bc187634aabf2f38b0febf962168883f26a3aaf8 /lib/ssl/test | |
parent | 5ef5d6a216815c13ce671df07bd0125b317f5969 (diff) | |
download | otp-c034b8ce819cfe1171720499387815ae8dc84bc9.tar.gz otp-c034b8ce819cfe1171720499387815ae8dc84bc9.tar.bz2 otp-c034b8ce819cfe1171720499387815ae8dc84bc9.zip |
Add the option { hibernate_after, int() } to ssl:connect and ssl:listen
When making an SSL connection (either as client or as server), the
process implementing the connection may use as much as hundreds of
kilobytes of memory, even when idle. This is problematic for any
application maintaining more than just a few SSL connections.
This patch introduces the option { hibernate_after, int() } to the
ssl:connect and ssl:listen functions, making the SSL connection
process go into hibernation after the specified number of milliseconds
of inactivity. This will reduce the memory used by the process to
just a few hundred bytes, making applications with thousands or
more SSL connections feasible, as long as most of the connections
are idle for most of the time (which is typically the case).
The approach of making the process go into hibernation only after
some time of inactivity was chosen because hibernation incurs some
CPU usage, and it is therefore not desirable for a process to
hibernate after each call.
Diffstat (limited to 'lib/ssl/test')
-rw-r--r-- | lib/ssl/test/Makefile | 3 | ||||
-rw-r--r-- | lib/ssl/test/ssl_basic_SUITE.erl | 44 | ||||
-rw-r--r-- | lib/ssl/test/ssl_test_lib.erl | 12 |
3 files changed, 52 insertions, 7 deletions
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile index 823401c863..fd3b6d06ad 100644 --- a/lib/ssl/test/Makefile +++ b/lib/ssl/test/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1999-2010. All Rights Reserved. +# Copyright Ericsson AB 1999-2011. 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 @@ -60,6 +60,7 @@ ERL_FILES = $(MODULES:%=%.erl) HRL_FILES = ssl_test_MACHINE.hrl HRL_FILES_SRC = \ + ssl_int.hrl \ ssl_alert.hrl \ ssl_handshake.hrl diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 8495ddb1d7..4f0907027f 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -29,6 +29,7 @@ -include_lib("public_key/include/public_key.hrl"). -include("ssl_alert.hrl"). +-include("ssl_int.hrl"). -define('24H_in_sec', 86400). -define(TIMEOUT, 60000). @@ -250,7 +251,9 @@ all() -> unknown_server_ca_accept_backwardscompatibilty, %%different_ca_peer_sign, no_reuses_session_server_restart_new_cert, - no_reuses_session_server_restart_new_cert_file, reuseaddr]. + no_reuses_session_server_restart_new_cert_file, reuseaddr, + hibernate + ]. groups() -> []. @@ -3319,6 +3322,45 @@ reuseaddr(Config) when is_list(Config) -> ssl_test_lib:close(Client1). %%-------------------------------------------------------------------- + +hibernate(doc) -> + ["Check that an SSL connection that is started with option " + "{hibernate_after, 1000} indeed hibernates after 1000ms of " + "inactivity"]; + +hibernate(suite) -> + []; + +hibernate(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + {Client, #sslsocket{pid=Pid}} = ssl_test_lib:start_client([return_socket, + {node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, [{hibernate_after, 1000}|ClientOpts]}]), + + { current_function, { _M, _F, _A } } = + process_info(Pid, current_function), + + timer:sleep(1100), + + { current_function, { erlang, hibernate, 3} } = + process_info(Pid, current_function), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- send_recv_result(Socket) -> diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl index f6ccbe85e3..8c639aa312 100644 --- a/lib/ssl/test/ssl_test_lib.erl +++ b/lib/ssl/test/ssl_test_lib.erl @@ -128,12 +128,14 @@ remove_close_msg(ReconnectTimes) -> remove_close_msg(ReconnectTimes -1) end. - start_client(Args) -> - Result = spawn_link(?MODULE, run_client, [Args]), + Result = spawn_link(?MODULE, run_client, [lists:delete(return_socket, Args)]), receive - connected -> - Result + { connected, Socket } -> + case lists:member(return_socket, Args) of + true -> { Result, Socket }; + false -> Result + end end. run_client(Opts) -> @@ -145,7 +147,7 @@ run_client(Opts) -> test_server:format("ssl:connect(~p, ~p, ~p)~n", [Host, Port, Options]), case rpc:call(Node, ssl, connect, [Host, Port, Options]) of {ok, Socket} -> - Pid ! connected, + Pid ! { connected, Socket }, test_server:format("Client: connected~n", []), %% In specail cases we want to know the client port, it will %% be indicated by sending {port, 0} in options list! |