ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/SemaphoreSet.pm
(Generate patch)

Comparing Coro/Coro/SemaphoreSet.pm (file contents):
Revision 1.7 by root, Tue Nov 6 20:34:11 2001 UTC vs.
Revision 1.21 by pcg, Sat Nov 15 03:53:10 2003 UTC

28 28
29=cut 29=cut
30 30
31package Coro::SemaphoreSet; 31package Coro::SemaphoreSet;
32 32
33no warnings qw(uninitialized); 33BEGIN { eval { require warnings } && warnings->unimport ("uninitialized") }
34 34
35use Coro (); 35use Coro ();
36 36
37$VERSION = 0.52; 37$VERSION = "0.9";
38 38
39=item new [inital count] 39=item new [inital count]
40 40
41Creates a new sempahore set with the given initial lock count for each 41Creates a new sempahore set with the given initial lock count for each
42individual semaphore. See L<Coro::Semaphore>. 42individual semaphore. See L<Coro::Semaphore>.
50=item $sem->down($id) 50=item $sem->down($id)
51 51
52Decrement the counter, therefore "locking" the named semaphore. This 52Decrement the counter, therefore "locking" the named semaphore. This
53method waits until the semaphore is available if the counter is zero. 53method waits until the semaphore is available if the counter is zero.
54 54
55=item $status = $sem->timed_down($id, $timeout)
56
57Like C<down>, but returns false if semaphore couldn't be acquired within
58$timeout seconds, otherwise true.
59
55=cut 60=cut
56 61
57sub down { 62sub down {
58 my $sem = ($_[0][1]{$_[1]} ||= [$_[0][0]]); 63 my $sem = ($_[0][1]{$_[1]} ||= [$_[0][0]]);
59 while ($sem->[0] <= 0) { 64 while ($sem->[0] <= 0) {
60 push @{$sem->[1]}, $Coro::current; 65 push @{$sem->[1]}, $Coro::current;
61 Coro::schedule; 66 Coro::schedule;
62 } 67 }
63 --$sem->[0]; 68 --$sem->[0];
69}
70
71sub timed_down {
72 require Coro::Timer;
73 my $timeout = Coro::Timer::timeout($_[2]);
74
75 my $sem = ($_[0][1]{$_[1]} ||= [$_[0][0]]);
76 while ($sem->[0] <= 0) {
77 push @{$sem->[1]}, $Coro::current;
78 Coro::schedule;
79 if ($timeout) {
80 # ugly as hell.
81 for (0..$#{$sem->[1]}) {
82 if ($sem->[1][$_] == $Coro::current) {
83 splice @{$sem->[1]}, $_, 1;
84 return;
85 }
86 }
87 die;
88 }
89 }
90 --$sem->[0];
91 return 1;
64} 92}
65 93
66=item $sem->up($id) 94=item $sem->up($id)
67 95
68Unlock the semaphore again. 96Unlock the semaphore again.
108=item $guard = $sem->guard($id) 136=item $guard = $sem->guard($id)
109 137
110This method calls C<down> and then creates a guard object. When the guard 138This method calls C<down> and then creates a guard object. When the guard
111object is destroyed it automatically calls C<up>. 139object is destroyed it automatically calls C<up>.
112 140
141=item $guard = $sem->timed_guard($id, $timeout)
142
143Like C<guard>, but returns undef if semaphore couldn't be acquired within
144$timeout seconds, otherwise the guard object.
145
113=cut 146=cut
114 147
115sub guard { 148sub guard {
116 &down; 149 &down;
117 # double indirection because bless works on the referenced
118 # object, not (only) on the reference itself.
119 bless [@_], Coro::SemaphoreSet::Guard::; 150 bless [@_], Coro::SemaphoreSet::guard::;
120} 151}
121 152
153sub timed_guard {
154 &timed_down
155 ? bless [$_[0], $_[1]], Coro::SemaphoreSet::guard::
156 : ();
157}
158
122sub Coro::SemaphoreSet::Guard::DESTROY { 159sub Coro::SemaphoreSet::guard::DESTROY {
123 &up(@{$_[0]}); 160 &up(@{$_[0]});
124} 161}
125 162
1261; 1631;
127 164

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines