=begin pod

=TITLE class Lock

=SUBTITLE Low-level thread locking primitive

    class Lock {}

A Lock is a low-level constructor for ensuring that only one thread works with
a certain object at a given time, or runs a piece of code (called the
I<critical section>).

    my $x = 0;
    my $l = Lock.new;
    await (^10).map: {
        start {
            $l.protect({ $x++ });
        }
    }
    say $x;         # 10

Locks are reentrant, that is, a thread that holds the lock can lock it again
without blocking.

High-level Perl 6 code should avoid the direct usage of locks, because they
are not composable. Instead, high-level constructs such as
L<Promise|/type/Promise>, L<Channel|/type/Channel> and Supply should be used
whenever possible.

=head1 Methods

=head2 method protect

Defined as:

    method protect(Lock:D: &code)

Runs C<&code> and makes sure it is only run in one thread at once.

    my $l = Lock.new;
    $l.protect({ #`( some unsafe operations here ) 1 + 1; });

=head2 method lock

Defined as:

    method lock(Lock:D:)

Acquires the lock. If it is currently not available, waits for it.

    my $l = Lock.new;
    $l.lock;

=head2 method unlock

Defined as:

    method unlock(Lock:D:)

Releases the lock.

    my $l = Lock.new;
    $l.lock;
    $l.unlock;

=head2 method condition

Defined as:

=begin code :skip-test
my class ConditionVariable {
    method wait();
    method signal();
    method signal_all();
}

method condition(Lock:D:) returns ConditionVariable:D
=end code

Returns a condition variable. Compare
L<http://web.stanford.edu/class/cs140/cgi-bin/lecture.php?topic=locks> or
L<https://en.wikipedia.org/wiki/Monitor_%28synchronization%29> for background.

    my $l = Lock.new;
    $l.condition;

=end pod
