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

Comparing Coro/Coro/Semaphore.pm (file contents):
Revision 1.21 by root, Mon Sep 24 01:36:20 2001 UTC vs.
Revision 1.36 by pcg, Wed Nov 5 20:02:46 2003 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines