[erlang-questions] Replacing ets tables - renaming and race condition
Mats Cronqvist
mats.cronqvist@REDACTED
Wed Apr 4 15:23:04 CEST 2007
Paulo Sérgio Almeida wrote:
> Ulf, even if my problem is much simpler than if there were dependencies
> between lookups, it is not that simple ...
>
> Namely, your sketched solution still has a race condition.
>
>> Tab = ets:new(tmp, []),
>> compute(Tab),
>> ets:insert(switch_table, {current, Tab}).
>
> If some process does:
>
>> lookup(Key) ->
>> Tab = ets:lookup_element(switch, current, 2),
>> ets:lookup(Tab, Key).
>
> it could do the lookup_element, but be interrupted before doing the
> lookup. This means the lookup could be to a table that no longer exists
> if the recompute is:
>
>> recompute() ->
>> Old = ets:lookup_element(switch, current, 2),
>> New = ets:new(tmp, []),
>> compute(New),
>> ets:insert(switch, {current, New}),
>> ets:delete(Old).
>
> So, we still have a problem :
we still have a problem if and only if recompute insists on deleting the old
table.
what you're shooting for is having all ets access look something like this;
Tab = get_current_tab(),
do_all_kinds_of_ets_stuff(Tab)
where Tab must not disappear while we're in do_all_kinds_of_ets_stuff/1.
realistically, the time spent in do_all_kinds_of_ets_stuff/1 is much less than
the time between calls to recompute/0. if so, something like this would do.
recompute() ->
New = ets:new(tmp, []),
Current = ets:lookup_element(switch, current, 2),
Old = ets:lookup_element(switch, old, 2),
compute(New),
ets:insert(switch, {current, New}),
ets:insert(switch, {old, Current}),
ets:delete(Old).
mats
More information about the erlang-questions
mailing list