ソースを参照

ft: 优化之后提交

master
SisMaker 1年前
コミット
80b409d5c8
1個のファイルの変更100行の追加0行の削除
  1. +100
    -0
      src/eGLock.erl

+ 100
- 0
src/eGLock.erl ファイルの表示

@ -0,0 +1,100 @@
-module(eGLock).
-include("eGLock.hrl").
-export([
lockApply/2
, lockApply/3
]).
-spec lockApply(KeyOrKeys :: tuple() | [tuple()], MFAOrFun :: {M :: atom(), F :: atom(), Args :: list()} | {Fun :: function(), Args :: list()}) -> term().
lockApply(KeyOrKeys, MFAOrFun) ->
lockApply(KeyOrKeys, MFAOrFun, ?LockTimeOut).
-spec lockApply(KeyOrKeys :: tuple() | [tuple()], MFAOrFun :: {M :: atom(), F :: atom(), Args :: list()} | {Fun :: function(), Args :: list()}, TimeOut :: integer() | infinity) -> term().
lockApply(KeyOrKeys, MFAOrFun, TimeOut) ->
case KeyOrKeys of
{_, _} ->
lockApply(KeyOrKeys, MFAOrFun, TimeOut, erlang:system_time(millisecond));
_ ->
lockApplys(KeyOrKeys, MFAOrFun, TimeOut, erlang:system_time(millisecond))
end.
-define(CASE(Cond, Then, That), case Cond of true -> Then; _ -> That end).
lockApply(Key, MFAOrFun, TimeOut, FirstTime) ->
case ets:insert_new(?EtsGLockKey, Key) of
true ->
try doApply(MFAOrFun)
catch C:R:S ->
{error, {lock_apply_error, {C, R, S}}}
after
ets:delete(?EtsGLockKey, element(1, Key)),
ok
end;
_ ->
loopTry(Key, MFAOrFun, TimeOut, FirstTime)
end.
loopTry(Key, MFAOrFun, TimeOut, FirstTime) ->
receive
after ?ReTryTime ->
case ets:lookup(?EtsGLockKey, element(1, Key)) of
[] ->
lockApply(Key, MFAOrFun, TimeOut, FirstTime);
_ ->
case TimeOut of
infinity ->
loopTry(Key, MFAOrFun, TimeOut, FirstTime);
_ ->
LTimeOut = TimeOut - abs(erlang:system_time(millisecond) - FirstTime),
case LTimeOut =< 0 of
true ->
{error, {lock_timeout, Key}};
_ ->
loopTry(Key, MFAOrFun, TimeOut, FirstTime)
end
end
end
end.
lockApplys(Keys, MFAOrFun, TimeOut, FirstTime) ->
case ets:insert_new(?EtsGLockKey, Keys) of
true ->
try doApply(MFAOrFun)
catch C:R:S ->
{error, {lock_apply_error, {C, R, S}}}
after
[ets:delete(?EtsGLockKey, element(1, OneKey)) || OneKey <- Keys],
ok
end;
_ ->
loopTrys(Keys, MFAOrFun, TimeOut, FirstTime)
end.
loopTrys(Keys, MFAOrFun, TimeOut, FirstTime) ->
receive
after ?ReTryTime ->
[Key | _] = Keys,
case ets:lookup(?EtsGLockKey, element(1, Key)) of
[] ->
lockApplys(Keys, MFAOrFun, TimeOut, FirstTime);
_ ->
case TimeOut of
infinity ->
loopTrys(Keys, MFAOrFun, TimeOut, FirstTime);
_ ->
LTimeOut = TimeOut - abs(erlang:system_time(millisecond) - FirstTime),
case LTimeOut =< 0 of
true ->
{error, {lock_timeout, Keys}};
_ ->
loopTrys(Keys, MFAOrFun, TimeOut, FirstTime)
end
end
end
end.
doApply({M, F, A}) ->
apply(M, F, A);
doApply({Fun, Args}) ->
apply(Fun, Args).

読み込み中…
キャンセル
保存