[erlang-questions] Preventing a race condition when using dets/ets

Mats Cronqvist <>
Wed May 7 17:25:23 CEST 2008


Dave Bryson wrote:
> On May 7, 2008, at 8:57 AM, Paul Fisher wrote:
>
>   
>> On Wed, 2008-05-07 at 08:48 -0500, Dave Bryson wrote:
>>     
>>> Say for example I have the following code:
>>>
>>> {_,N} = ets:lookup(?MODULE,counter),
>>> ok = ets:insert(?MODULE, {counter, N+1}).
>>>       
>> Two options:
>> 1) use ets:update_counter/3, if it is really an integer value with the
>> table being public
>> 2) have a gen_server process "own" the ets table and perform all
>> operations on behalf of callers (gen_server:call/2, 3) with the table
>> being private
>>     
>
> Thanks for the response. So just to be clear, if the only access to  
> the ets table is through calls to a gen_server process, it  
> (gen_server) will ensure that only one process at a time can access  
> the ets table?
  the only way to ensure atomicity when using ets is to have a table 
owning process (it doesn't have to be a gen_server, of course). you can 
set the 'private' attribute on the table (see ets:new/2) to ensure this.

  given this;
15>   F = fun(T)-> [{_,N}] = 
ets:lookup(T,counter),ets:insert(T,{counter, N+1}) end.
#Fun<erl_eval.6.56006484>
16> ets:new(foo,[named_table,private]).
foo
17> ets:insert(foo,{counter,0}).      
true
18> F(foo).                           
true
19> ets:lookup(foo,counter).          
[{counter,1}]

the gen_server could be pretty generic;

<boilerplate />
handle_call({atomic,F},_From,State) ->   {reply,F(?MODULE),State}.

  warning: code is totally untested. only proven correct by extensive 
model checking.

  mats


-------------- next part --------------
A non-text attachment was scrubbed...
Name: mats_cronqvist.vcf
Type: text/x-vcard
Size: 179 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20080507/e7879135/attachment.vcf>


More information about the erlang-questions mailing list