From fbcc835d06dc017aebaf0b837bf56ca524f3c9c5 Mon Sep 17 00:00:00 2001 From: Paul Joseph Davis Date: Fri, 19 Mar 2010 15:20:12 +0000 Subject: Avoid a possible race condition. The old code was relying on a DOWN message being sent before a call to get the current ref counter. Its possible that the request was sent before that happened causing an error. The new code doesn't use messages from the child process and instead uses a monitor to know when the process went down. Then it sends up to 10,000 requests for the current count. Theoretically the only way this will fail is if the DOWN message to the ref_counter is delayed for an extremely long time or dropped entirely. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@925264 13f79535-47bb-0310-9956-ffa450edef68 --- test/etap/100-ref-counter.t | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'test') diff --git a/test/etap/100-ref-counter.t b/test/etap/100-ref-counter.t index 6f18d828..8f996d04 100755 --- a/test/etap/100-ref-counter.t +++ b/test/etap/100-ref-counter.t @@ -27,17 +27,14 @@ main(_) -> loop() -> receive - {ping, From} -> - From ! pong + close -> ok end. wait() -> receive - _ -> - ok - after - 1000 -> - throw(timeout_error) + {'DOWN', _, _, _, _} -> ok + after 1000 -> + throw(timeout_error) end. test() -> @@ -94,11 +91,23 @@ test() -> "Sanity checking that the Pid was re-added." ), - ChildPid1 ! {ping, self()}, + erlang:monitor(process, ChildPid1), + ChildPid1 ! close, wait(), - etap:is( - couch_ref_counter:count(RefCtr), - 1, + + CheckFun = fun + (Iter, nil) -> + case couch_ref_counter:count(RefCtr) of + 1 -> Iter; + _ -> nil + end; + (_, Acc) -> + Acc + end, + Result = lists:foldl(CheckFun, nil, lists:seq(1, 10000)), + etap:isnt( + Result, + nil, "The referer count was decremented automatically on process exit." ), -- cgit v1.2.3