diff options
author | Micael Karlberg <[email protected]> | 2012-01-05 12:09:37 +0100 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2012-01-05 12:09:37 +0100 |
commit | 5edcd0d6372d73124e4160a2bbc5b81853642fc5 (patch) | |
tree | 4a3eb2e9f1d5c4599e3afe2d77e18a0f09651328 /lib/inets/src/http_client/httpc_manager.erl | |
parent | 345ffc04c94d583ec829bacf2807fe1562b7f72c (diff) | |
download | otp-5edcd0d6372d73124e4160a2bbc5b81853642fc5.tar.gz otp-5edcd0d6372d73124e4160a2bbc5b81853642fc5.tar.bz2 otp-5edcd0d6372d73124e4160a2bbc5b81853642fc5.zip |
[inets/httpc] Add proper code change code
Added proper code to handle code upgrade/downgrade.
The manager and handler(s) are interdependant which
makes it a bit tricky.
OTP-9847
Diffstat (limited to 'lib/inets/src/http_client/httpc_manager.erl')
-rw-r--r-- | lib/inets/src/http_client/httpc_manager.erl | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index 4262abc5d0..3d846c2bff 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -214,8 +214,6 @@ update_session(ProfileName, SessionId, Pos, Value) -> ets:update_element(SessionDbName, SessionId, {Pos, Value}). - - %%-------------------------------------------------------------------- %% Function: delete_session(SessionId, ProfileName) -> _ %% SessionId - {{Host, Port}, HandlerPid} @@ -572,9 +570,70 @@ terminate(_, State) -> %% Func: code_change(_OldVsn, State, Extra) -> {ok, NewState} %% Purpose: Convert process state when code is changed %%-------------------------------------------------------------------- -code_change(_OldVsn, State, _Extra) -> +code_change(_, + #state{session_db = SessionDB} = State, + upgrade_from_pre_5_7_3) -> + Upgrade = + fun({session, + Id, ClientClose, Scheme, Socket, SocketType, QueueLen, Type}) -> + {ok, #session{id = Id, + client_close = ClientClose, + scheme = Scheme, + socket = Socket, + socket_type = SocketType, + queue_length = QueueLen, + type = Type}}; + (_) -> % Already upgraded (by handler) + ignore + end, + (catch update_session_table(SessionDB, Upgrade)), + {ok, State}; + +code_change(_, + #state{session_db = SessionDB} = State, + downgrade_to_pre_5_7_3) -> + Downgrade = + fun(#session{id = Id, + client_close = ClientClose, + scheme = Scheme, + socket = Socket, + socket_type = SocketType, + queue_length = QueueLen, + type = Type}) -> + {ok, {session, + Id, ClientClose, Scheme, Socket, SocketType, + QueueLen, Type}}; + (_) -> % Already downgraded (by handler) + ignore + end, + (catch update_session_table(SessionDB, Downgrade)), + {ok, State}; + +code_change(_, State, _) -> {ok, State}. +%% This function is to catch everything that calls through the cracks... +update_session_table(SessionDB, Transform) -> + ets:safe_fixtable(SessionDB, true), + update_session_table(SessionDB, ets:first(SessionDB), Transform), + ets:safe_fixtable(SessionDB, false). + +update_session_table(_SessionDB, '$end_of_table', _Transform) -> + ok; +update_session_table(SessionDB, Key, Transform) -> + case ets:lookup(SessionDB, Key) of + [OldSession] -> + case Transform(OldSession) of + {ok, NewSession} -> + ets:insert(SessionDB, NewSession); + ignore -> + ok + end; + _ -> + ok + end, + update_session_table(SessionDB, ets:next(SessionDB, Key), Transform). + %%-------------------------------------------------------------------- %% Internal functions |