Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
gproc
gproc-0.8.0-git.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gproc-0.8.0-git.patch of Package gproc
diff --git a/.travis.yml b/.travis.yml index bd09c45..671b550 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,6 @@ script: "GPROC_DIST=true rebar get-deps compile eunit" otp_release: - 20.0 - 19.3 - - 19.2 - - 19.1 - 19.0 - 18.3 - 18.2.1 diff --git a/src/gproc.erl b/src/gproc.erl index f2ee2c2..d84e76c 100644 --- a/src/gproc.erl +++ b/src/gproc.erl @@ -2358,7 +2358,7 @@ handle_call({demonitor, {T,l,_} = Key, Ref, Pid}, _From, S) [{K, Opts}] -> Opts1 = gproc_lib:remove_monitor(Opts, Pid, Ref), ets:insert(?TAB, {K, Opts1}), - case gproc_lib:does_pid_monitor(Pid, Opts) of + case gproc_lib:does_pid_monitor(Pid, Opts1) of true -> ok; false -> @@ -2489,6 +2489,8 @@ handle_reg_call(Key, Pid, Val, Attrs, Op, S) -> %% actually pretty bad, if it ever happens {reply, badarg, S} end; + already_registered -> + {reply, badarg, S}; false -> {reply, badarg, S} end. diff --git a/src/gproc_lib.erl b/src/gproc_lib.erl old mode 100644 new mode 100755 index 4d51399..13ee3f8 --- a/src/gproc_lib.erl +++ b/src/gproc_lib.erl @@ -291,13 +291,13 @@ remove_monitors(Key, Pid, MPid) -> [{_, r}] -> []; [{K, Opts}] when is_list(Opts) -> - case lists:keyfind(monitors, 1, Opts) of + case lists:keyfind(monitor, 1, Opts) of false -> []; {_, Ms} -> - Ms1 = [{P,R} || {P,R} <- Ms, + Ms1 = [{P,R,T} || {P,R,T} <- Ms, P =/= MPid], - NewMs = lists:keyreplace(monitors, 1, Opts, {monitors,Ms1}), + NewMs = lists:keyreplace(monitor, 1, Opts, {monitor,Ms1}), ets:insert(?TAB, {K, NewMs}), [{insert, [{{Pid,Key}, NewMs}]}] end; @@ -306,7 +306,7 @@ remove_monitors(Key, Pid, MPid) -> end. does_pid_monitor(Pid, Opts) -> - case lists:keyfind(monitors, 1, Opts) of + case lists:keyfind(monitor, 1, Opts) of false -> false; {_, Ms} -> @@ -393,7 +393,7 @@ select_monitors([], _, Acc) -> Acc. remove_monitor_pid([{monitor, Mons}|T], Pid) -> - [{monitors, [M || M <- Mons, + [{monitor, [M || M <- Mons, element(1, M) =/= Pid]}|T]; remove_monitor_pid([H|T], Pid) -> [H | remove_monitor_pid(T, Pid)]; diff --git a/src/gproc_pool.erl b/src/gproc_pool.erl index 9e6b056..5657a10 100644 --- a/src/gproc_pool.erl +++ b/src/gproc_pool.erl @@ -359,9 +359,8 @@ pick(Pool, Sz, round_robin, Ret) -> case ets:next(gproc, {{n,l,[?MODULE,Pool,Next]},n}) of {{n,l,[?MODULE,Pool,Actual,_Name]} = Pick, _} -> case Actual - Next of - Diff when Diff > 1 -> - gproc:update_counter( - ?POOL_CUR(Pool), shared, {Diff, Sz, 1}), + Diff when Diff > 0 -> + incr(Pool, Diff, Sz), ret(Pick, Ret); _ -> ret(Pick, Ret) @@ -370,8 +369,6 @@ pick(Pool, Sz, round_robin, Ret) -> case ets:next(gproc, {{n,l,[?MODULE,Pool,0]}, n}) of {{n,l,[?MODULE,Pool,Actual1,_Name1]} = Pick, _} -> incr(Pool, Sz-Next+Actual1, Sz), - %% gproc:update_counter( - %% ?POOL_CUR(Pool), shared, {Sz-Next+Actual1, Sz, 1}), ret(Pick, Ret); _ -> false @@ -827,24 +824,29 @@ remove_worker_(Pool, Name) -> do_remove_worker_(Pool, Name) -> K = ?POOL(Pool), + AutoSize = gproc:get_attribute(K, shared, auto_size), Ws0 = get_workers_(K), - Ws1 = del_slot(Name, Ws0), + Ws1 = del_slot(Name, Ws0, AutoSize), gproc:unreg_shared(?POOL_WRK(Pool, Name)), - case (NewLen = length(Ws1)) - length(Ws0) of - 0 -> ok; - Diff when Diff < 0 -> - {_, Type} = gproc:get_value(K, shared), - gproc:set_value_shared(K, {NewLen, Type}) + case AutoSize of + false -> ok; + true -> + case (NewLen = length(Ws1)) - length(Ws0) of + 0 -> ok; + Diff when Diff < 0 -> + {_, Type} = gproc:get_value(K, shared), + gproc:set_value_shared(K, {NewLen, Type}) + end end, gproc:set_attributes_shared(K, [{workers, Ws1}]), ok. -del_slot(Name, [{Name,_}]) -> +del_slot(Name, [{Name,_}], true) -> []; -del_slot(Name, [{Name, Pos}|T]) -> +del_slot(Name, [{Name, Pos}|T], _AutoSize) -> [Pos|T]; -del_slot(Name, [H|T]) -> - [H|del_slot(Name, T)]. +del_slot(Name, [H|T], AutoSize) -> + [H|del_slot(Name, T, AutoSize)]. find_slot(Name, _, [], Sz, _, Auto) -> case {Sz, Auto} of diff --git a/test/gproc_tests.erl b/test/gproc_tests.erl old mode 100644 new mode 100755 index a9812e5..65f6841 --- a/test/gproc_tests.erl +++ b/test/gproc_tests.erl @@ -154,6 +154,8 @@ reg_test_() -> , ?_test(t_is_clean()) , {spawn, ?_test(?debugVal(t_monitor_follow()))} , ?_test(t_is_clean()) + , {spawn, ?_test(?debugVal(t_two_monitoring_processes_one_dies()))} + , ?_test(t_is_clean()) , {spawn, ?_test(?debugVal(t_monitor_demonitor()))} , ?_test(t_is_clean()) , {spawn, ?_test(?debugVal(t_subscribe()))} @@ -162,6 +164,12 @@ reg_test_() -> , ?_test(t_is_clean()) , {spawn, ?_test(?debugVal(t_simple_pool()))} , ?_test(t_is_clean()) + , {spawn, ?_test(?debugVal(t_pool_add_worker_size_1_no_auto_size()))} + , ?_test(t_is_clean()) + , {spawn, ?_test(?debugVal(t_pool_add_worker_size_2_no_auto_size()))} + , ?_test(t_is_clean()) + , {spawn, ?_test(?debugVal(t_pool_round_robin_disconnect_worker()))} + , ?_test(t_is_clean()) ]}. t_simple_reg() -> @@ -920,6 +928,23 @@ t_monitor_follow() -> [exit(P,kill) || P <- [P1,P3]], ok. +t_two_monitoring_processes_one_dies() -> + Name = ?T_NAME, + P = t_spawn_reg(Name), + Ref = gproc:monitor(Name), + {P2, R2} = spawn_monitor(fun() -> gproc:monitor(Name) end), + receive + {'DOWN', R2, process, P2, normal} -> ok + end, + exit(P, kill), + receive + M -> + ?assertEqual({gproc, unreg, Ref, Name}, M) + after 1000 -> + error(timeout) + end +. + t_monitor_demonitor() -> Name = ?T_NAME, P1 = t_spawn(Selective = true), @@ -1003,6 +1028,75 @@ t_simple_pool()-> %% should be able to delete the pool now ?assertEqual( gproc_pool:delete(p1), ok). +%% verifying #167 - Removing a worker from a pool does not make room +%% for a new worker (size was erroneously adjusted down, though auto_size = false) +t_pool_add_worker_size_1_no_auto_size() -> + ok = gproc_pool:new(p2, direct, [{size, 1}, {auto_size, false}]), + [] = gproc_pool:defined_workers(p2), + Pos1 = gproc_pool:add_worker(p2, worker1), + [{worker1, Pos1, 0}] = gproc_pool:defined_workers(p2), + io:fwrite("G = ~p~n", [ets:tab2list(gproc)]), + true = gproc_pool:remove_worker(p2, worker1), + [] = gproc_pool:defined_workers(p2), %% the pool seems to be empty + Pos2 = gproc_pool:add_worker(p2, worker2), %% throws error:pool_full + true = is_integer(Pos2), + true = gproc_pool:force_delete(p2). + +t_pool_add_worker_size_2_no_auto_size() -> + gproc_pool:new(p3, direct, [{size, 2}, {auto_size, false}]), + gproc_pool:add_worker(p3, worker1), + gproc_pool:add_worker(p3, worker2), + gproc_pool:remove_worker(p3, worker2), + gproc_pool:add_worker(p3, worker3), + gproc_pool:force_delete(p3). + +t_pool_round_robin_disconnect_worker() -> + gproc_pool:new(p), + gproc_pool:add_worker(p, w1), + gproc_pool:add_worker(p, w2), + gproc_pool:add_worker(p, w3), + Work = fun(W) -> spawn(fun() -> gproc_pool:connect_worker(p, W), fun F() -> F() end() end) end, + + %% disc first + W1 = Work(w1), + W2 = Work(w2), + W3 = Work(w3), + timer:sleep(10), + ?assertEqual([W1, W2, W3], [ P || {_, P} <- gproc_pool:active_workers(p)]), + ?assertEqual([W1, W2, W3, W1, W2, W3, W1, W2, W3], [gproc_pool:pick_worker(p) || _ <- lists:seq(1, 9)]), + exit(W1, die), + timer:sleep(10), + ?assertEqual([W2, W3], [ P || {_, P} <- gproc_pool:active_workers(p)]), + ?assertEqual([W2, W3, W2, W3, W2, W3, W2, W3, W2], [gproc_pool:pick_worker(p) || _ <- lists:seq(1, 9)]), + + %% disc middle + W11 = Work(w1), + timer:sleep(10), + ?assertEqual([W11, W2, W3], [ P || {_, P} <- gproc_pool:active_workers(p)]), + ?assertEqual([W3, W11, W2, W3, W11, W2, W3, W11, W2], [gproc_pool:pick_worker(p) || _ <- lists:seq(1, 9)]), + exit(W2, die), + timer:sleep(10), + ?assertEqual([W11, W3], [ P || {_, P} <- gproc_pool:active_workers(p)]), + ?assertEqual([W3, W11, W3, W11, W3, W11, W3, W11, W3], [gproc_pool:pick_worker(p) || _ <- lists:seq(1, 9)]), + + %% disc last + W22 = Work(w2), + timer:sleep(10), + ?assertEqual([W11, W22, W3], [ P || {_, P} <- gproc_pool:active_workers(p)]), + ?assertEqual([W11, W22, W3, W11, W22, W3, W11, W22, W3], [gproc_pool:pick_worker(p) || _ <- lists:seq(1, 9)]), + exit(W3, die), + timer:sleep(10), + ?assertEqual([W11, W22], [ P || {_, P} <- gproc_pool:active_workers(p)]), + ?assertEqual([W11, W22, W11, W22, W11, W22, W11, W22, W11], [gproc_pool:pick_worker(p) || _ <- lists:seq(1, 9)]), + + %% restore + W33 = Work(w3), + timer:sleep(10), + ?assertEqual([W11, W22, W33], [ P || {_, P} <- gproc_pool:active_workers(p)]), + ?assertEqual([W22, W33, W11, W22, W33, W11, W22, W33, W11], [gproc_pool:pick_worker(p) || _ <- lists:seq(1, 9)]), + + gproc_pool:force_delete(p). + get_msg() -> receive M -> M
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor