File Coverage

blib/lib/Thread/RWLock.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             # RWLock.pm
2             #
3             # Copyright (c) 2001 Andreas Ferber. All rights reserved.
4             #
5             # $Id: RWLock.pm,v 1.2 2001/06/29 02:11:49 af Exp $
6              
7             =head1 NAME
8              
9             Thread::RWLock - rwlock implementation for perl threads
10              
11             =head1 SYNOPSIS
12              
13             use Thread::RWLock;
14              
15             my $rwlock = new Thread::RWLock;
16              
17             # Reader
18             $rwlock->down_read;
19             $rwlock->up_read;
20              
21             # Writer
22             $rwlock->down_write;
23             $rwlock->up_write;
24              
25             =head1 DESCRIPTION
26              
27             RWLocks provide a mechanism to regulate access to resources.
28             Multiple concurrent reader may hold the rwlock at the same
29             time, while a writer holds the lock exclusively.
30              
31             New reader threads are blocked if any writer are currently waiting to
32             obtain the lock. The read lock gets through after all write lock
33             requests have completed.
34              
35             This RWLock implementation also takes into account that one thread may
36             obtain multiple readlocks at the same time and prevents deadlocking in
37             this case.
38              
39             =cut
40              
41             package Thread::RWLock;
42              
43 1     1   3646 use Thread qw(cond_wait cond_broadcast);
  0            
  0            
44              
45             BEGIN {
46             $VERSION = do { my @r = (q$Revision: 1.2 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
47             }
48              
49             =head1 FUNCTIONS AND METHODS
50              
51             =over 8
52              
53             =item new
54              
55             C creates a new rwlock. The new rwlock is unlocked.
56              
57             =cut
58              
59             sub new {
60             my $class = shift;
61              
62             my $self = {};
63              
64             $self->{locks} = 0;
65             $self->{locker} = {};
66             $self->{writer} = 0;
67              
68             return bless $self, $class;
69             }
70              
71             =item down_read
72              
73             The C method obtains a read lock. If the lock is currantly
74             held by a writer or writer are waiting for the lock, C blocks
75             until the lock is available.
76              
77             =cut
78              
79             sub down_read :locked method {
80             my $self = shift;
81              
82             if ($self->{locker}->{Thread->self->tid}++) {
83             return;
84             }
85              
86             cond_wait $self until $self->{locks} >= 0 && $self->{writer} == 0;
87              
88             $self->{locker}->{Thread->self->tid} = 1;
89             $self->{locks}++;
90             }
91              
92             =item up_read
93              
94             Releases a read lock previously obtained via C.
95              
96             =cut
97              
98             sub up_read :locked method {
99             my $self = shift;
100              
101             if (--$self->{locker}->{Thread->self->tid} == 0) {
102             $self->{locks}--;
103             if ($self->{locks} == 0) {
104             cond_broadcast $self;
105             }
106             }
107             }
108              
109             =item down_write
110              
111             Obtains a write lock from the rwlock. Write locks are exclusive, so no
112             other reader or writer are allowed until the lock is released.
113             C blocks until the lock is available.
114              
115             =cut
116              
117             sub down_write :locked method {
118             my $self = shift;
119              
120             $self->{writer}++;
121             cond_wait $self until $self->{locks} == 0;
122             $self->{locks}--;
123             }
124              
125             =item up_write
126              
127             Release a write lock previously obtained via C.
128              
129             =cut
130              
131             sub up_write :locked method {
132             my $self = shift;
133              
134             $self->{writer}--;
135             $self->{locks} = 0;
136             cond_broadcast $self;
137             }
138              
139             =back
140              
141             =head1 SEE ALSO
142              
143             the Thread::Semaphore manpage
144              
145             =head1 AUTHOR
146              
147             Andreas Ferber
148              
149             =cut
150              
151             1;