ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro.pm
Revision: 1.11
Committed: Sun Jul 15 03:24:18 2001 UTC (22 years, 10 months ago) by root
Branch: MAIN
Changes since 1.10: +3 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Coro - coroutine process abstraction
4
5 =head1 SYNOPSIS
6
7 use Coro;
8
9 async {
10 # some asynchronous thread of execution
11 };
12
13 # alternatively create an async process like this:
14
15 sub some_func : Coro {
16 # some more async code
17 }
18
19 yield;
20
21 =head1 DESCRIPTION
22
23 =cut
24
25 package Coro;
26
27 use Coro::State;
28
29 use base Exporter;
30
31 $VERSION = 0.04;
32
33 @EXPORT = qw(async yield schedule);
34 @EXPORT_OK = qw($current);
35
36 {
37 use subs 'async';
38
39 my @async;
40
41 # this way of handling attributes simply is NOT scalable ;()
42 sub import {
43 Coro->export_to_level(1, @_);
44 my $old = *{(caller)[0]."::MODIFY_CODE_ATTRIBUTES"}{CODE};
45 *{(caller)[0]."::MODIFY_CODE_ATTRIBUTES"} = sub {
46 my ($package, $ref) = (shift, shift);
47 my @attrs;
48 for (@_) {
49 if ($_ eq "Coro") {
50 push @async, $ref;
51 } else {
52 push @attrs, @_;
53 }
54 }
55 return $old ? $old->($package, $name, @attrs) : @attrs;
56 };
57 }
58
59 sub INIT {
60 async pop @async while @async;
61 }
62 }
63
64 =item $main
65
66 This coroutine represents the main program.
67
68 =cut
69
70 our $main = new Coro;
71
72 =item $current
73
74 The current coroutine (the last coroutine switched to). The initial value is C<$main> (of course).
75
76 =cut
77
78 # maybe some other module used Coro::Specific before...
79 if ($current) {
80 $main->{specific} = $current->{specific};
81 }
82
83 our $current = $main;
84
85 =item $idle
86
87 The coroutine to switch to when no other coroutine is running. The default
88 implementation prints "FATAL: deadlock detected" and exits.
89
90 =cut
91
92 # should be done using priorities :(
93 our $idle = new Coro sub {
94 print STDERR "FATAL: deadlock detected\n";
95 exit(51);
96 };
97
98 # we really need priorities...
99 my @ready = (); # the ready queue. hehe, rather broken ;)
100
101 # static methods. not really.
102
103 =head2 STATIC METHODS
104
105 Static methods are actually functions that operate on the current process only.
106
107 =over 4
108
109 =item async { ... };
110
111 Create a new asynchronous process and return it's process object
112 (usually unused). When the sub returns the new process is automatically
113 terminated.
114
115 =cut
116
117 sub async(&) {
118 my $pid = new Coro $_[0];
119 $pid->ready;
120 $pid;
121 }
122
123 =item schedule
124
125 Calls the scheduler. Please note that the current process will not be put
126 into the ready queue, so calling this function usually means you will
127 never be called again.
128
129 =cut
130
131 my $prev;
132
133 sub schedule {
134 # should be done using priorities :(
135 ($prev, $current) = ($current, shift @ready || $idle);
136 Coro::State::transfer($prev, $current);
137 }
138
139 =item yield
140
141 Yield to other processes. This function puts the current process into the
142 ready queue and calls C<schedule>.
143
144 =cut
145
146 sub yield {
147 $current->ready;
148 &schedule;
149 }
150
151 =item terminate
152
153 Terminates the current process.
154
155 =cut
156
157 sub terminate {
158 &schedule;
159 }
160
161 =back
162
163 # dynamic methods
164
165 =head2 PROCESS METHODS
166
167 These are the methods you can call on process objects.
168
169 =over 4
170
171 =item new Coro \&sub;
172
173 Create a new process and return it. When the sub returns the process
174 automatically terminates. To start the process you must first put it into
175 the ready queue by calling the ready method.
176
177 =cut
178
179 sub new {
180 my $class = shift;
181 my $proc = $_[0];
182 bless {
183 _coro_state => new Coro::State ($proc ? sub { &$proc; &terminate } : $proc),
184 }, $class;
185 }
186
187 =item $process->ready
188
189 Put the current process into the ready queue.
190
191 =cut
192
193 sub ready {
194 push @ready, $_[0];
195 }
196
197 =back
198
199 =cut
200
201 1;
202
203 =head1 SEE ALSO
204
205 L<Coro::Channel>, L<Coro::Cont>, L<Coro::Specific>, L<Coro::Semaphore>,
206 L<Coro::Signal>, L<Coro::State>, L<Coro::Event>.
207
208 =head1 AUTHOR
209
210 Marc Lehmann <pcg@goof.com>
211 http://www.goof.com/pcg/marc/
212
213 =cut
214