ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/RWLock.pm
Revision: 1.68
Committed: Wed Jul 22 03:02:07 2009 UTC (14 years, 10 months ago) by root
Branch: MAIN
CVS Tags: rel-5_161
Changes since 1.67: +1 -1 lines
Log Message:
5.161

File Contents

# Content
1 =head1 NAME
2
3 Coro::RWLock - reader/write locks
4
5 =head1 SYNOPSIS
6
7 use Coro::RWLock;
8
9 $lck = new Coro::RWLock;
10
11 $lck->rdlock; # acquire read lock
12
13 $lck->unlock;
14
15 =head1 DESCRIPTION
16
17 This module implements reader/write locks. A read can be acquired for
18 read by many coroutines in parallel as long as no writer has locked it
19 (shared access). A single write lock can be acquired when no readers
20 exist. RWLocks basically allow many concurrent readers (without writers)
21 OR a single writer (but no readers).
22
23 =over 4
24
25 =cut
26
27 package Coro::RWLock;
28
29 BEGIN { eval { require warnings } && warnings->unimport ("uninitialized") }
30
31 use Coro ();
32
33 $VERSION = 5.161;
34
35 =item $l = new Coro::RWLock;
36
37 Create a new reader/writer lock.
38
39 =cut
40
41 sub new {
42 # [rdcount, [readqueue], wrcount, [writequeue]]
43 bless [0, [], 0, []], $_[0];
44 }
45
46 =item $l->rdlock
47
48 Acquire a read lock.
49
50 =item $l->tryrdlock
51
52 Try to acquire a read lock.
53
54 =cut
55
56 sub rdlock {
57 while ($_[0][0]) {
58 push @{$_[0][3]}, $Coro::current;
59 &Coro::schedule;
60 }
61 ++$_[0][2];
62 }
63
64 sub tryrdlock {
65 return if $_[0][0];
66 ++$_[0][2];
67 }
68
69 =item $l->wrlock
70
71 Acquire a write lock.
72
73 =item $l->trywrlock
74
75 Try to acquire a write lock.
76
77 =cut
78
79 sub wrlock {
80 while ($_[0][0] || $_[0][2]) {
81 push @{$_[0][1]}, $Coro::current;
82 &Coro::schedule;
83 }
84 ++$_[0][0];
85 }
86
87 sub trywrlock {
88 return if $_[0][0] || $_[0][2];
89 ++$_[0][0];
90 }
91
92 =item $l->unlock
93
94 Give up the rwlock.
95
96 =cut
97
98 sub unlock {
99 # either we are a reader or a writer. decrement accordingly.
100 if ($_[0][2]) {
101 return if --$_[0][2];
102 } else {
103 $_[0][0]--;
104 }
105 # now we have the choice between waking up a reader or a writer. we choose the writer.
106 if (@{$_[0][1]}) {
107 (shift @{$_[0][1]})->ready;
108 } elsif (@{$_[0][3]}) {
109 (shift @{$_[0][3]})->ready;
110 }
111 }
112
113 1;
114
115 =back
116
117 =head1 AUTHOR
118
119 Marc Lehmann <schmorp@schmorp.de>
120 http://home.schmorp.de/
121
122 =cut
123