./ct_report/coverage/pubsub_index.COVER.html

1 %%% ====================================================================
2 %%% ``The contents of this file are subject to the Erlang Public License,
3 %%% Version 1.1, (the "License"); you may not use this file except in
4 %%% compliance with the License. You should have received a copy of the
5 %%% Erlang Public License along with this software. If not, it can be
6 %%% retrieved via the world wide web at http://www.erlang.org/.
7 %%%
8 %%%
9 %%% Software distributed under the License is distributed on an "AS IS"
10 %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11 %%% the License for the specific language governing rights and limitations
12 %%% under the License.
13 %%%
14 %%%
15 %%% The Initial Developer of the Original Code is ProcessOne.
16 %%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne
17 %%% All Rights Reserved.''
18 %%% This software is copyright 2006-2015, ProcessOne.
19 %%%
20 %%%
21 %%% @copyright 2006-2015 ProcessOne
22 %%% @author Christophe Romain <christophe.romain@process-one.net>
23 %%% [http://www.process-one.net/]
24 %%% @end
25 %%% ====================================================================
26
27 %% important note:
28 %% new/1 and free/2 MUST be called inside a transaction bloc
29
30 -module(pubsub_index).
31 -author('christophe.romain@process-one.net').
32
33 -include("pubsub.hrl").
34
35 -export([init/0, new/1]).
36
37 init() ->
38 35 mongoose_mnesia:create_table(pubsub_index,
39 [{disc_copies, [node()]},
40 {attributes, record_info(fields, pubsub_index)}]).
41
42 new(Index) ->
43 %% Create a new short lived transaction to reduce lock contention
44 232 spawn_and_call(fun() -> mnesia:transaction(fun() -> new_transaction(Index) end) end).
45
46 new_transaction(Index) ->
47 237 case mnesia:wread({pubsub_index, Index}) of
48 [I] ->
49 230 Id = I#pubsub_index.last + 1,
50 230 mnesia:write(I#pubsub_index{last = Id}),
51 230 Id;
52 _ ->
53 2 mnesia:write(#pubsub_index{index = Index, last = 1, free = []}),
54 2 1
55 end.
56
57 spawn_and_call(F) ->
58 232 Ref = make_ref(),
59 232 Parent = self(),
60 232 FF = fun() -> Result = F(), Parent ! {call_result, Ref, Result} end,
61 232 Pid = spawn_monitor(FF),
62 232 receive
63 {call_result, Ref, Result} ->
64 232 {atomic, NewId} = Result,
65 232 erlang:demonitor(Ref, [flush]),
66 232 NewId;
67 {'DOWN', Ref, process, Pid, Reason} ->
68
:-(
erlang:error({spawn_and_call_failed, Reason})
69 after 5000 ->
70
:-(
erlang:demonitor(Ref, [flush]),
71
:-(
erlang:error(spawn_and_call_timeout)
72 end.
Line Hits Source