Module ce_locker

Description

Generic resource locker design pattern.

This is an example of how a resource locker can be coded in Erlang. For a more practical, distributed locker, see the global module in the kernel application of OTP.

One locker is created per resource you wish to lock. These lockers are named and their names are stored in a public ETS table. Locker names can be arbitary terms. This allows non-re-entrant functions to be called exclusively with call/3.

This is of course voluntary locking (unless you somehow arrange for the locker to be used on otherwise normal calls, e.g. with a parse transform.)

Function Index

Exported Functions
call/3Calls a non-re-entrant function.
create_locker_table/1Called by start/0.
lock/1See lock/2.
lock/2Locks a resource, preventing other processes from accessing it.
new/1Creates a new locker for a named resource.
server/0Called by new/1.
start/0Starts the resource locking subsystem.
test/0
test2/0
unlock/1Unlocks a resource, allowing other processes to access it.
Internal Documented Functions
server/1Main locker server loop.

Exported Functions

call/3

call(Module::atom(), Function::atom(), Args::[term()]) -> term()

Calls a non-re-entrant function. Does this by first locking the function by it's name, then calling the function, then unlocking it. The name of the function in this case is {Module, Function, Arity} where Arity is determined by the length of Args.

create_locker_table/1

create_locker_table(Parent::pid()) -> never_returns

Called by start/0. Should not be called by user code.

lock/1

lock(locker()) -> {ok, Result} | {error, Reason}

Equivalent to lock(locker(), infinity).

lock/2

lock(locker(), Timeout::integer()) -> {ok, Result} | {error, Reason}

Locks a resource, preventing other processes from accessing it. The resource may specified by name, or by locker pid. If a locker for the named resource does not exist, one is created.

new/1

new(Name::term()) -> pid()

Creates a new locker for a named resource.

server/0

server() -> never_returns

Called by new/1. Should not be called by user code.

start/0

start() -> pid()

Starts the resource locking subsystem. Creates an ETS table to map resource names to lockers.

test/0

test() -> term()

test2/0

test2() -> term()

unlock/1

unlock(locker()) -> {ok, Result} | {error, Reason}

Unlocks a resource, allowing other processes to access it. The resource may specified by name, or by locker pid.

Documented Internal Functions

server/1

server(Queue::[pid()]) -> never_returns

Main locker server loop. Queue is the list of pids that are waiting for this resource; the head of this list is the pid which currently owns the lock.