aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2019-01-25 13:05:18 +0100
committerGitHub <[email protected]>2019-01-25 13:05:18 +0100
commit5ed2f3d9757c9f2b8e49a4796e2a384c938d80dd (patch)
tree980ffc10ff8629430acc0fd514232457939a65cd /lib/mnesia
parent7cd0271e226ddd727867b0f923a00d9f58167a5f (diff)
parent8332bff4ceebd08d103623f59f7761d8e9367f69 (diff)
downloadotp-5ed2f3d9757c9f2b8e49a4796e2a384c938d80dd.tar.gz
otp-5ed2f3d9757c9f2b8e49a4796e2a384c938d80dd.tar.bz2
otp-5ed2f3d9757c9f2b8e49a4796e2a384c938d80dd.zip
Merge pull request #2029 from richcarl/mnesia-read-local-if-available
Mnesia should always use the local context if available OTP-15550
Diffstat (limited to 'lib/mnesia')
-rw-r--r--lib/mnesia/src/mnesia.erl40
1 files changed, 24 insertions, 16 deletions
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 223dba3f90..77afb8250c 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -838,18 +838,20 @@ read(Tid, Ts, Tab, Key, LockKind)
tid ->
Store = Ts#tidstore.store,
Oid = {Tab, Key},
- Objs =
- case LockKind of
- read ->
- mnesia_locker:rlock(Tid, Store, Oid);
- write ->
- mnesia_locker:rwlock(Tid, Store, Oid);
- sticky_write ->
- mnesia_locker:sticky_rwlock(Tid, Store, Oid);
- _ ->
- abort({bad_type, Tab, LockKind})
- end,
- add_written(?ets_lookup(Store, Oid), Tab, Objs);
+ ObjsFun =
+ fun() ->
+ case LockKind of
+ read ->
+ mnesia_locker:rlock(Tid, Store, Oid);
+ write ->
+ mnesia_locker:rwlock(Tid, Store, Oid);
+ sticky_write ->
+ mnesia_locker:sticky_rwlock(Tid, Store, Oid);
+ _ ->
+ abort({bad_type, Tab, LockKind})
+ end
+ end,
+ add_written(?ets_lookup(Store, Oid), Tab, ObjsFun, LockKind);
_Protocol ->
dirty_read(Tab, Key)
end;
@@ -1202,14 +1204,20 @@ add_previous(_Tid, Ts, _Type, Tab) ->
%% This routine fixes up the return value from read/1 so that
%% it is correct with respect to what this particular transaction
%% has already written, deleted .... etc
+%% The actual read from the table is not done if not needed due to local
+%% transaction context, and if so, no extra read lock is needed either.
-add_written([], _Tab, Objs) ->
- Objs; % standard normal fast case
-add_written(Written, Tab, Objs) ->
+add_written([], _Tab, ObjsFun, _LockKind) ->
+ ObjsFun(); % standard normal fast case
+add_written(Written, Tab, ObjsFun, LockKind) ->
case val({Tab, setorbag}) of
bag ->
- add_written_to_bag(Written, Objs, []);
+ add_written_to_bag(Written, ObjsFun(), []);
+ _ when LockKind == read;
+ LockKind == write ->
+ add_written_to_set(Written);
_ ->
+ _ = ObjsFun(), % Fall back to request new lock and read from source
add_written_to_set(Written)
end.