diff --git a/src/bdberl.erl b/src/bdberl.erl index 05a9cf7..b2d7a42 100644 --- a/src/bdberl.erl +++ b/src/bdberl.erl @@ -40,7 +40,8 @@ truncate/0, truncate/1, delete_database/1, cursor_open/1, cursor_next/0, cursor_prev/0, cursor_current/0, cursor_close/0, - register_logger/0]). + register_logger/0, + stop/0]). -include("bdberl.hrl"). @@ -357,7 +358,7 @@ txn_begin(Opts) -> ok -> receive ok -> ok; - {error, Reason} -> {error, decode_rc(Reason)} + {error, Reason} -> {error, Reason} end; Error -> @@ -2066,6 +2067,27 @@ register_logger() -> [] = erlang:port_control(get_port(), ?CMD_REGISTER_LOGGER, <<>>), ok. +%%-------------------------------------------------------------------- +%% @doc +%% Stop bdberl - stops the bdberl_logger process so that when +%% all processes using bdberl terminate then the driver will be unloaded. +%% +%% @spec stop() -> ok +%% +%% @end +%%-------------------------------------------------------------------- +-spec stop() -> ok. + +stop() -> + %% Look for logging process -- make sure it's running and/or registered + case whereis(bdberl_logger) of + undefined -> + ok; + _ -> + ok = supervisor:terminate_child(kernel_safe_sup, bdberl_logger), + ok = supervisor:delete_child(kernel_safe_sup, bdberl_logger) + end. + %% ==================================================================== %% Internal functions diff --git a/test/bdberl_SUITE.erl b/test/bdberl_SUITE.erl index 82b0830..4ceea04 100644 --- a/test/bdberl_SUITE.erl +++ b/test/bdberl_SUITE.erl @@ -41,7 +41,8 @@ all() -> mutex_stat_should_report_on_success, txn_stat_should_report_on_success, data_dirs_info_should_report_on_success, - lg_dir_info_should_report_on_success]. + lg_dir_info_should_report_on_success, + start_after_stop_should_be_safe]. @@ -322,3 +323,34 @@ data_dirs_info_should_report_on_success(_Config) -> lg_dir_info_should_report_on_success(_Config) -> {ok, _LgDir, _Fsid, _MBytesAvail} = bdberl:get_lg_dir_info(). +%% Check the bdberl_logger gets reinstalled after stopping +start_after_stop_should_be_safe(_Config) -> + + %% Make sure bdberl_logger is running by using bdberl + Self = self(), + F = fun() -> + bdberl:log_stat(), + Self ! ok + end, + spawn(F), + receive + ok -> + ok + end, + {ok, Drivers} = erl_ddll:loaded_drivers(), + true = lists:keymember(bdberl_logger, 1, supervisor:which_children(kernel_safe_sup)), + + %% Make sure bdberl_logger is really removed on stop + bdberl:stop(), + false = lists:keymember(bdberl_logger, 1, supervisor:which_children(kernel_safe_sup)), + + %% A bdb operation to open the port and get it re-registered + spawn(F), + receive + ok -> + ok + end, + true = lists:keymember(bdberl_logger, 1, supervisor:which_children(kernel_safe_sup)), + ok. + +