1-module(upgradee). 2 3-export([dispatch_loop/0]). 4 5-ifdef(VERSION_1). 6-define(VERSION,1). 7 8-export([exp1/0]). % only exported in v1 9-export([exp1loc2/0]). % exported in v1, local in v2 10-export([exp1exp2/0]). % exported in v1 and v2 11-export([get_local_fun/1]). 12-export([get_exp1exp2_fun/0]). 13-export([exp1exp2_fun/0]). 14 15exp1() -> ?VERSION. 16loc1() -> ?VERSION. 17 18-endif. % VERSION_1 19 20-ifdef(VERSION_2). 21-define(VERSION,2). 22 23-export([exp2/0]). 24-export([loc1exp2/0]). 25-export([exp1exp2/0]). 26-export([get_local_fun/1]). 27-export([get_exp1exp2_fun/0]). 28-export([exp1exp2_fun/0]). 29 30exp2() -> ?VERSION. 31loc2() -> ?VERSION. 32 33-endif. % VERSION_2 34 35exp1exp2() -> ?VERSION. 36exp1loc2() -> ?VERSION. 37loc1exp2() -> ?VERSION. 38loc1loc2() -> ?VERSION. 39 40get_local_fun(Env) -> fun() -> {?VERSION,Env} end. 41get_exp1exp2_fun() -> fun ?MODULE:exp1exp2_fun/0. 42 43exp1exp2_fun() -> 44 ?VERSION. 45 46dispatch_loop() -> 47 receive 48 upgrade_order -> 49 %%erlang:display({"upgradee version", ?VERSION, "got upgrade_order"}), 50 ?MODULE:dispatch_loop(); 51 52 Msg -> 53 %%erlang:display({"upgradee version", ?VERSION, "got msg", Msg}), 54 {Func,Ret} = case Msg of 55 %% Local calls 56 {Pid, local, F=exp1} -> 57 {F, local_exp1()}; 58 {Pid, local, F=loc1} -> 59 {F, local_loc1()}; 60 {Pid, local, F=exp1exp2} -> 61 {F, catch exp1exp2()}; 62 {Pid, local, F=exp1loc2} -> 63 {F, catch exp1loc2()}; 64 {Pid, local, F=loc1exp2} -> 65 {F, catch loc1exp2()}; 66 {Pid, local, F=loc1loc2} -> 67 {F, catch loc1loc2()}; 68 {Pid, local, F=exp2} -> 69 {F, local_exp2()}; 70 {Pid, local, F=loc2} -> 71 {F, local_loc2()}; 72 73 %% Extern calls to own module 74 {Pid, external, F=exp1} -> 75 {F, catch ?MODULE:exp1()}; 76 {Pid, external, F=loc1} -> 77 {F, catch ?MODULE:loc1()}; 78 {Pid, external, F=exp1exp2} -> 79 {F, catch ?MODULE:exp1exp2()}; 80 {Pid, external, F=exp1loc2} -> 81 {F, catch ?MODULE:exp1loc2()}; 82 {Pid, external, F=loc1exp2} -> 83 {F, catch ?MODULE:loc1exp2()}; 84 {Pid, external, F=loc1loc2} -> 85 {F, catch ?MODULE:loc1loc2()}; 86 {Pid, external, F=exp2} -> 87 {F, catch ?MODULE:exp2()}; 88 {Pid, external, F=loc2} -> 89 {F, catch ?MODULE:loc2()}; 90 91 %% External calls to other module 92 {Pid, other, F=exp1} -> 93 {F, catch other:exp1()}; 94 {Pid, other, F=loc1} -> 95 {F, catch other:loc1()}; 96 {Pid, other, F=exp1exp2} -> 97 {F, catch other:exp1exp2()}; 98 {Pid, other, F=exp1loc2} -> 99 {F, catch other:exp1loc2()}; 100 {Pid, other, F=loc1exp2} -> 101 {F, catch other:loc1exp2()}; 102 {Pid, other, F=loc1loc2} -> 103 {F, catch other:loc1loc2()}; 104 {Pid, other, F=exp2} -> 105 {F, catch other:exp2()}; 106 {Pid, other, F=loc2} -> 107 {F, catch other:loc2()} 108 end, 109 Pid ! {self(), call_result, Func, Ret}, 110 111 dispatch_loop() % A local call, we don't want to upgrade the dispatcher 112 end. 113 114 115 116-ifdef(VERSION_1). 117local_exp1() -> catch exp1(). 118local_loc1() -> catch loc1(). 119-else. 120local_exp1() -> 121 %%erlang:display({"upgradee:local_exp1 in version", ?VERSION}), 122 {cannot_compile,?VERSION}. 123local_loc1() -> {cannot_compile,?VERSION}. 124-endif. 125 126-ifdef(VERSION_2). 127local_exp2() -> catch exp2(). 128local_loc2() -> catch loc2(). 129-else. 130local_exp2() -> 131 %%erlang:display({"upgradee:local_exp2 in version", ?VERSION}), 132 {cannot_compile,?VERSION}. 133local_loc2() -> 134 {cannot_compile,?VERSION}. 135-endif. 136