From 5075b58c668d2e90a6e115cdd37a83686e03d8d0 Mon Sep 17 00:00:00 2001 From: SisMaker <1713699517@qq.com> Date: Mon, 15 Apr 2024 14:14:25 +0800 Subject: [PATCH] =?UTF-8?q?ft:=20=E4=BC=98=E5=8C=96=E4=BF=AE=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/eGLock.hrl | 6 +---- src/eALock.erl | 65 +++++++++++++++++++++++----------------------- src/eALockMgr.erl | 17 ------------ 3 files changed, 34 insertions(+), 54 deletions(-) diff --git a/include/eGLock.hrl b/include/eGLock.hrl index 5632bd8..233addd 100644 --- a/include/eGLock.hrl +++ b/include/eGLock.hrl @@ -1,9 +1,6 @@ %% 锁key -define(EtsGLockKey, '$EtsGLockKey'). -%% 锁key --define(EtsGLockPid, '$EtsGLockPid'). - %% 默认超时时间单位:Ms -define(LockTimeOut, 5000). @@ -11,9 +8,8 @@ -define(ReTryTime, 10). -define(eELockMgr, eELockMgr). --define(eALockMgr, eALockMgr). %% 数组数量 -define(eALockSize, 1048576). -%% 数组数量 +%% atomics索引 -define(eALockRef, eALockRef). diff --git a/src/eALock.erl b/src/eALock.erl index e81e576..1e19a29 100644 --- a/src/eALock.erl +++ b/src/eALock.erl @@ -14,67 +14,56 @@ lockApply(KeyOrKeys, MFAOrFun) -> -spec lockApply(KeyOrKeys :: term() | [term()], MFAOrFun :: {M :: atom(), F :: atom(), Args :: list()} | {Fun :: function(), Args :: list()}, TimeOut :: integer() | infinity) -> term(). lockApply(KeyOrKeys, MFAOrFun, TimeOut) -> - GLockMgrPid = persistent_term:get(?eALockMgr), ALockRef = persistent_term:get(?eALockRef), CurPid = self(), - PidInt = eGPidInt:termInt(CurPid), + PidInt = eGPidInt:pidToInt(CurPid), case is_list(KeyOrKeys) of true -> KeyIxs = getKexIxs(KeyOrKeys, []), - lockApplys(KeyIxs, KeyOrKeys, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut); + lockApplys(KeyIxs, KeyOrKeys, ALockRef, CurPid, PidInt, MFAOrFun, TimeOut); _ -> - lockApply(erlang:phash2(KeyOrKeys, ?eALockSize) + 1, KeyOrKeys, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut) + lockApply(erlang:phash2(KeyOrKeys, ?eALockSize) + 1, KeyOrKeys, ALockRef, CurPid, PidInt, MFAOrFun, TimeOut) end. -lockApply(KeyIx, Key, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut) -> - link(GLockMgrPid), - ets:insert(?EtsGLockPid, {CurPid, KeyIx}), - case atomics:compare_exchange(ALockRef, KeyIx, 0, PidInt) of +lockApply(KeyIx, Key, ALockRef, CurPid, PidInt, MFAOrFun, TimeOut) -> + case tryLockOne(KeyIx, ALockRef, PidInt) of ok -> try doApply(MFAOrFun) catch C:R:S -> {error, {lock_apply_error, {C, R, S}}} after atomics:exchange(ALockRef, KeyIx, 0), - ets:delete(?EtsGLockPid, CurPid), - unlink(GLockMgrPid), ok end; _ -> - loopTry(KeyIx, Key, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut) + loopTry(KeyIx, Key, ALockRef, CurPid, PidInt, MFAOrFun, TimeOut) end. -loopTry(KeyIx, Key, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut) -> +loopTry(KeyIx, Key, ALockRef, CurPid, PidInt, MFAOrFun, TimeOut) -> receive after ?ReTryTime -> LTimeOut = ?CASE(TimeOut == infinity, TimeOut, TimeOut - ?ReTryTime), case LTimeOut >= 0 of true -> - case atomics:compare_exchange(ALockRef, KeyIx, 0, PidInt) of + case tryLockOne(KeyIx, ALockRef, PidInt) of ok -> try doApply(MFAOrFun) catch C:R:S -> {error, {lock_apply_error, {C, R, S}}} after atomics:exchange(ALockRef, KeyIx, 0), - ets:delete(?EtsGLockPid, CurPid), - unlink(GLockMgrPid), ok end; _ -> - loopTry(KeyIx, Key, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, LTimeOut) + loopTry(KeyIx, Key, ALockRef, CurPid, PidInt, MFAOrFun, LTimeOut) end; _ -> - ets:delete(?EtsGLockPid, CurPid), - unlink(GLockMgrPid), {error, {lock_timeout, Key}} end end. -lockApplys(KeyIxs, Keys, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut) -> +lockApplys(KeyIxs, Keys, ALockRef, CurPid, PidInt, MFAOrFun, TimeOut) -> CurPid = self(), - link(GLockMgrPid), - ets:insert(?EtsGLockPid, {CurPid, KeyIxs}), case tryLockAll(KeyIxs, ALockRef, PidInt, []) of ok -> try doApply(MFAOrFun) @@ -82,15 +71,13 @@ lockApplys(KeyIxs, Keys, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOu {error, {lock_apply_error, {C, R, S}}} after [atomics:exchange(ALockRef, KeyIx, 0) || KeyIx <- KeyIxs], - ets:delete(?EtsGLockPid, CurPid), - unlink(GLockMgrPid), ok end; _ -> - loopTrys(KeyIxs, Keys, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut) + loopTrys(KeyIxs, Keys, ALockRef, CurPid, PidInt, MFAOrFun, TimeOut) end. -loopTrys(KeyIxs, Keys, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut) -> +loopTrys(KeyIxs, Keys, ALockRef, CurPid, PidInt, MFAOrFun, TimeOut) -> receive after ?ReTryTime -> LTimeOut = ?CASE(TimeOut == infinity, TimeOut, TimeOut - ?ReTryTime), @@ -103,16 +90,12 @@ loopTrys(KeyIxs, Keys, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut) {error, {lock_apply_error, {C, R, S}}} after [atomics:exchange(ALockRef, KeyIx, 0) || KeyIx <- KeyIxs], - ets:delete(?EtsGLockPid, CurPid), - unlink(GLockMgrPid), ok end; _ -> - loopTrys(KeyIxs, Keys, ALockRef, CurPid, PidInt, GLockMgrPid, MFAOrFun, TimeOut) + loopTrys(KeyIxs, Keys, ALockRef, CurPid, PidInt, MFAOrFun, TimeOut) end; _ -> - ets:delete(?EtsGLockPid, CurPid), - unlink(GLockMgrPid), {error, {lock_timeout, Keys}} end end. @@ -122,14 +105,32 @@ getKexIxs([Key | Keys], IxAcc) -> KeyIx = erlang:phash2(Key, ?eALockSize) + 1, getKexIxs(Keys, ?CASE(lists:member(KeyIx, IxAcc), IxAcc, [KeyIx | IxAcc])). +tryLockOne(KeyIx, ALockRef, PidInt) -> + case atomics:compare_exchange(ALockRef, KeyIx, 0, PidInt) of + ok -> + ok; + OldPidInt -> + case is_process_alive(eGPidInt:intToPid(OldPidInt)) of + true -> + false; + _ -> + case atomics:compare_exchange(ALockRef, KeyIx, OldPidInt, PidInt) of + ok -> + ok; + _ -> + false + end + end + end. + tryLockAll([], _ALockRef, _PidInt, _LockAcc) -> ok; tryLockAll([KeyIx | KeyIxs], ALockRef, PidInt, LockAcc) -> - case atomics:compare_exchange(ALockRef, KeyIx, 0, PidInt) of + case tryLockOne(KeyIx, ALockRef, PidInt) of ok -> tryLockAll(KeyIxs, ALockRef, PidInt, [KeyIx | LockAcc]); _ -> - [atomics:exchange(ALockRef, OneLock, 0) || OneLock <- LockAcc], + [atomics:compare_exchange(ALockRef, OneLock, PidInt, 0) || OneLock <- LockAcc], false end. diff --git a/src/eALockMgr.erl b/src/eALockMgr.erl index 8f819cd..046ebfb 100644 --- a/src/eALockMgr.erl +++ b/src/eALockMgr.erl @@ -23,8 +23,6 @@ init([]) -> process_flag(trap_exit, true), ATLockRef = atomics:new(?eALockSize, [{signed, false}]), persistent_term:put(?eALockRef, ATLockRef), - persistent_term:put(?eALockMgr, self()), - ets:new(?EtsGLockPid, [named_table, set, public, {write_concurrency, auto}]), {ok, #state{}}. handle_call(_Request, _From, State) -> @@ -33,21 +31,6 @@ handle_call(_Request, _From, State) -> handle_cast(_Request, State) -> {noreply, State}. -handle_info({'EXIT', Pid, _Reason}, State) -> - case ets:take(?EtsGLockPid, Pid) of - [] -> ignore; - [{_Pid, KeyIxOrKeyIxs}] -> - ALockRef = persistent_term:get(?eALockRef), - PidInt = eGPidInt:termInt(Pid), - case is_integer(KeyIxOrKeyIxs) of - true -> - atomics:compare_exchange(ALockRef, KeyIxOrKeyIxs, PidInt, 0); - _ -> - [atomics:compare_exchange(ALockRef, KeyIx, PidInt, 0) || KeyIx <- KeyIxOrKeyIxs], - ok - end - end, - {noreply, State}; handle_info(_Info, State) -> {noreply, State}.