[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