[erlang-questions] dialyzer: possible race condition with insert after lookup
Ulf Wiger
ulf.wiger@REDACTED
Sun Oct 23 21:00:29 CEST 2011
This might please Dialyzer (I haven't tried):
bump(Key, Value) ->
try ets:update_counter(stats, Key, {4, Value})
catch
error:_ ->
ets:insert_new(stats, {Key, now(), count, 0}),
ets:update_counter(stats, Key, {4, Value})
end.
The point of trying first with a try … catch would be that it's slightly faster than doing an insert_new() for every bump, when it's really only expected to be needed the first time.
Another solution is to ensure that all counters exist from the start.
BR,
Ulf
On 23 Oct 2011, at 20:00, Joel Reymont wrote:
> Consider this piece of code
>
> handle_cast({bump, Key, Value}, Data) ->
> %% cannot update counter on a non-existing record,
> %% so a lookup cannot be avoided
> _ = case ets:lookup(stats, Key) of
> [] -> ets:insert(stats, [{Key, now(), count, Value}]);
> _ -> ets:update_counter(stats, Key, {4, Value})
> end,
> {noreply, Data};
>
> Dialyzer reports that
>
> stats.erl:150: The call ets:insert('stats',[{_,{non_neg_integer(),non_neg_integer(),non_neg_integer()},'count',_},...]) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('stats',Key::any()) call in stats.erl on line 149
>
> What is the proper way to fix this?
>
> Thanks, Joel
>
> --------------------------------------------------------------------------
> - for hire: mac osx device driver ninja, kernel extensions and usb drivers
> ---------------------+------------+---------------------------------------
> http://wagerlabs.com | @wagerlabs | http://www.linkedin.com/in/joelreymont
> ---------------------+------------+---------------------------------------
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
Ulf Wiger, CTO, Erlang Solutions, Ltd.
http://erlang-solutions.com
More information about the erlang-questions
mailing list