Skip to content

Latest commit

 

History

History
367 lines (191 loc) · 10.6 KB

locks.md

File metadata and controls

367 lines (191 loc) · 10.6 KB

Module locks

Official API for the 'locks' system.

Description

This module contains the supported interface functions for

  • starting and stopping a transaction (agent)
  • acquiring locks via an agent
  • awaiting requested locks

Function Index

await_all_locks/1Await the results of all requested locks.
begin_transaction/0Equivalent to begin_transaction([], []).
begin_transaction/1Equivalent to begin_transaction(Objects, []).
begin_transaction/2Starts a transaction agent.
change_flag/3
end_transaction/1Terminates the transaction agent, releasing all locks.
lock/2Equivalent to lock(Agent, OID, write, [node()], all).
lock/3Equivalent to lock(Agent, OID, Mode, [node()], all).
lock/4Equivalent to lock(Agent, OID, Mode, Nodes, all).
lock/5Acquire a lock on object.
lock_nowait/2Equivalent to lock_nowait(Agent, OID, write, [node()], all).
lock_nowait/3Equivalent to lock_nowait(Agent, OID, Mode, [node()], all).
lock_nowait/4Equivalent to lock_nowait(Agent, OID, Mode, Nodes, all).
lock_objects/2Asynchronously locks several objects at once.
spawn_agent/0
spawn_agent/1
unwatch/2Remove a subscription created by watch/2.
watch/2Subscribe to lock state changes.
watchers/1List the process IDs of watchers of OID on the current node.

Function Details

await_all_locks/1


await_all_locks(Agent::agent()) -> lock_result()



Await the results of all requested locks.

This function blocks until all requested locks have been acquired, or it is determined that they cannot be (and the transaction aborts).

The return value is {have_all_locks | have_none, Deadlocks}, where Deadlocks is a list of {OID, Node} pairs that were either surrendered or released as a result of an abort triggered by the deadlock analysis.

begin_transaction/0


begin_transaction() -> {agent(), lock_result()}



Equivalent to begin_transaction([], []).

begin_transaction/1


begin_transaction(Objects::objs()) -> {agent(), lock_result()}



Equivalent to begin_transaction(Objects, []).

begin_transaction/2


begin_transaction(Objects::objs(), Options::options()) -> {agent(), lock_result()}



Starts a transaction agent.

Valid options are:

  • {abort_on_deadlock, boolean()} - default: false. Normally, when a deadlock is detected, the involved agents will resolve it by one agent surrendering a lock, but this is not always desireable. With this option, agents will abort if a deadlock is detected.
  • {client, pid()} - defaults to self(). The agent will accept lock requests only from the designated client.
  • {await_nodes, boolean()} - default: false. If nodes required to serve a lock request are off-line, with {await_nodes, false}, the transaction will abort; with {await_nodes, true} the transaction will wait for them to return and try to re-acquire the locks.

change_flag/3

change_flag(Agent, Option, Bool) -> any()

end_transaction/1


end_transaction(Agent::pid()) -> ok



Terminates the transaction agent, releasing all locks.

Note that there is no unlock() operation. The way to release locks is to end the transaction.

lock/2


lock(Agent::agent(), OID::oid()) -> {ok, deadlocks()}



Equivalent to lock(Agent, OID, write, [node()], all).

lock/3


lock(Agent::agent(), OID::oid(), Mode::mode()) -> {ok, deadlocks()}



Equivalent to lock(Agent, OID, Mode, [node()], all).

lock/4


lock(Agent::agent(), OID::oid(), Mode::mode(), Nodes::where()) -> {ok, deadlocks()}



Equivalent to lock(Agent, OID, Mode, Nodes, all).

lock/5


lock(Agent::agent(), OID::oid(), Mode::mode(), Nodes::where(), Req::req()) -> {ok, deadlocks()}



Acquire a lock on object.

This operation requires an active transaction agent (see begin_transaction/2).

The object identifier is a non-empty list, where each element represents a level in a lock tree. For example, in a database Db, with tables and objects, object locks could be given as [Db, Table, Key], table locks as [Db, Table] and schema locks [Db].

Mode can be either read (shared) or write (exclusive). If possible, read locks will be upgraded to write locks when requested. Specifically, this can be done if no other agent also hold a read lock, and there are no waiting agents on the lock (directly or indirectly). If the lock cannot be upgraded, the read lock will be removed and a write lock request will be inserted in the lock queue.

The lock request is synchronous, and will return when this and all previous lock requests have been granted. The return value is {ok, Deadlocks}, where Deadlocks is a list of objects that have caused a deadlock.

lock_nowait/2


lock_nowait(Agent::agent(), OID::oid()) -> ok



Equivalent to lock_nowait(Agent, OID, write, [node()], all).

lock_nowait/3


lock_nowait(Agent::agent(), OID::oid(), Mode::mode()) -> ok



Equivalent to lock_nowait(Agent, OID, Mode, [node()], all).

lock_nowait/4


lock_nowait(Agent::agent(), OID::oid(), Mode::mode(), Nodes::where()) -> ok



Equivalent to lock_nowait(Agent, OID, Mode, Nodes, all).

lock_objects/2


lock_objects(Agent::agent(), Objects::objs()) -> ok



Asynchronously locks several objects at once.

This function is equivalent to repeatedly calling lock_nowait/5, essentially:

  lists:foreach(
      fun({OID, Mode}) -> lock_nowait(Agent, OID, Mode);
         ({OID, Mode, Nodes}) -> lock_nowait(Agent, OID, Mode, Nodes);
         ({OID, Mode, Nodes, Req}) -> lock_nowait(Agent,OID,Mode,Nodes,Req)
      end, Objects)

spawn_agent/0


spawn_agent() -> {ok, agent()}



spawn_agent/1


spawn_agent(Options::options()) -> {ok, agent()}



unwatch/2


unwatch(OID::oid(), Nodes::[node()]) -> ok



Remove a subscription created by watch/2.

This function removes a subscription created by watch/2.

watch/2


watch(OID::oid(), Nodes::[node()]) -> ok



Subscribe to lock state changes.

This function ensures that #lock_info{} messages are sent for each lock state change in OID on Nodes. The subscription is not persistent; if a node dies, the knowledge of processes watching locks on that node will disappear.

watchers/1


watchers(OID::oid()) -> [pid()]



List the process IDs of watchers of OID on the current node.