aboutsummaryrefslogtreecommitdiffstats
path: root/lib/percept/src/percept_db.erl
diff options
context:
space:
mode:
authorAhmed Omar <[email protected]>2010-12-15 11:26:18 +0100
committerAhmed Omar <[email protected]>2010-12-15 11:26:18 +0100
commit638a610d0b7ada7b2099b6127410aafb9fae3313 (patch)
tree4ccebf3de17485b91a3d5c3137abe7c53bc993a1 /lib/percept/src/percept_db.erl
parent9f4dd4934d427f0fb2caeb034115e0227cc4610a (diff)
downloadotp-638a610d0b7ada7b2099b6127410aafb9fae3313.tar.gz
otp-638a610d0b7ada7b2099b6127410aafb9fae3313.tar.bz2
otp-638a610d0b7ada7b2099b6127410aafb9fae3313.zip
Fixes a race condition found in percept_db start/1 function.
When function start/1 finds an instance of percept_db running, it will send a message to stop it and spawn a process to start a new one, which leads to a race condition. The function will return {restarted, pid()} but the pid() will die once it tries to create the ets table.
Diffstat (limited to 'lib/percept/src/percept_db.erl')
-rw-r--r--lib/percept/src/percept_db.erl49
1 files changed, 40 insertions, 9 deletions
diff --git a/lib/percept/src/percept_db.erl b/lib/percept/src/percept_db.erl
index edb0d79a29..52e9afb78f 100644
--- a/lib/percept/src/percept_db.erl
+++ b/lib/percept/src/percept_db.erl
@@ -33,7 +33,7 @@
]).
-include("percept.hrl").
-
+-define(STOP_TIMEOUT, 1000).
%%==========================================================================
%%
%% Type definitions
@@ -77,17 +77,32 @@
start() ->
case erlang:whereis(percept_db) of
undefined ->
- Pid = spawn( fun() -> init_percept_db() end),
- erlang:register(percept_db, Pid),
- {started, Pid};
+ {started, do_start()};
PerceptDB ->
- erlang:unregister(percept_db),
- PerceptDB ! {action, stop},
- Pid = spawn( fun() -> init_percept_db() end),
- erlang:register(percept_db, Pid),
- {restarted, Pid}
+ {restarted, restart(PerceptDB)}
end.
+%% @spec restart(pid()) -> pid()
+%% @private
+%% @doc restarts the percept database.
+
+-spec restart(pid())-> pid().
+
+restart(PerceptDB)->
+ stop_sync(PerceptDB),
+ do_start().
+
+%% @spec do_start(pid()) -> pid()
+%% @private
+%% @doc starts the percept database.
+
+-spec do_start()-> pid().
+
+do_start()->
+ Pid = spawn( fun() -> init_percept_db() end),
+ erlang:register(percept_db, Pid),
+ Pid.
+
%% @spec stop() -> not_started | {stopped, Pid}
%% Pid = pid()
%% @doc Stops the percept database.
@@ -103,6 +118,22 @@ stop() ->
{stopped, Pid}
end.
+%% @spec stop_sync(pid()) -> true
+%% @private
+%% @doc Stops the percept database, with a synchronous call.
+
+-spec stop_sync(pid())-> true.
+
+stop_sync(Pid)->
+ MonitorRef = erlang:monitor(process, Pid),
+ stop(),
+ receive
+ {'DOWN', MonitorRef, _Type, Pid, _Info}->
+ true
+ after ?STOP_TIMEOUT->
+ exit(Pid, kill)
+ end.
+
%% @spec insert(tuple()) -> ok
%% @doc Inserts a trace or profile message to the database.