ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro.pm
Revision: 1.22
Committed: Mon Jul 23 02:14:19 2001 UTC (22 years, 10 months ago) by root
Branch: MAIN
Changes since 1.21: +23 -9 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.8 Coro - coroutine process abstraction
4 root 1.1
5     =head1 SYNOPSIS
6    
7     use Coro;
8    
9 root 1.8 async {
10     # some asynchronous thread of execution
11 root 1.2 };
12    
13 root 1.8 # alternatively create an async process like this:
14 root 1.6
15 root 1.8 sub some_func : Coro {
16     # some more async code
17     }
18    
19 root 1.22 cede;
20 root 1.2
21 root 1.1 =head1 DESCRIPTION
22    
23 root 1.14 This module collection manages coroutines. Coroutines are similar to
24     Threads but don't run in parallel.
25    
26     This module is still experimental, see the BUGS section below.
27    
28 root 1.20 In this module, coroutines are defined as "callchain + lexical variables
29     + @_ + $_ + $@ + $^W), that is, a coroutine has it's own callchain, it's
30     own set of lexicals and it's own set of perl's most important global
31     variables.
32    
33 root 1.21 WARNING: When using this module, make sure that, at program end, no
34     coroutines are still running OR just call exit before falling off the
35     end. The reason for this is that some coroutine of yours might have called
36     into a C function, and falling off the end of main:: results in returning
37     to that C function instead if to the main C interpreter.
38    
39 root 1.22 WARNING: Unless you really know what you are doing, do NOT do context
40     switches inside callbacks from the XS level. The reason for this is
41     similar to the reason above: A callback calls a perl function, this
42     perl function does a context switch, some other callback is called, the
43     original function returns from it - to what? To the wrong XS function,
44     with totally different return values. Unfortunately, this includes
45     callbacks done by perl itself (tie'd variables!).
46    
47     The only workaround for this is to do coroutines on C level.
48    
49 root 1.8 =cut
50    
51     package Coro;
52    
53     use Coro::State;
54    
55     use base Exporter;
56    
57 root 1.20 $VERSION = 0.10;
58 root 1.8
59 root 1.22 @EXPORT = qw(async cede schedule terminate current);
60 root 1.8 @EXPORT_OK = qw($current);
61    
62     {
63     my @async;
64    
65     # this way of handling attributes simply is NOT scalable ;()
66     sub import {
67     Coro->export_to_level(1, @_);
68     my $old = *{(caller)[0]."::MODIFY_CODE_ATTRIBUTES"}{CODE};
69     *{(caller)[0]."::MODIFY_CODE_ATTRIBUTES"} = sub {
70     my ($package, $ref) = (shift, shift);
71     my @attrs;
72     for (@_) {
73     if ($_ eq "Coro") {
74     push @async, $ref;
75     } else {
76 root 1.17 push @attrs, $_;
77 root 1.8 }
78     }
79 root 1.17 return $old ? $old->($package, $ref, @attrs) : @attrs;
80 root 1.8 };
81     }
82    
83     sub INIT {
84 root 1.20 &async(pop @async) while @async;
85 root 1.8 }
86     }
87    
88     =item $main
89 root 1.2
90 root 1.8 This coroutine represents the main program.
91 root 1.1
92     =cut
93    
94 root 1.9 our $main = new Coro;
95 root 1.8
96 root 1.19 =item $current (or as function: current)
97 root 1.1
98 root 1.8 The current coroutine (the last coroutine switched to). The initial value is C<$main> (of course).
99 root 1.1
100 root 1.8 =cut
101    
102     # maybe some other module used Coro::Specific before...
103     if ($current) {
104     $main->{specific} = $current->{specific};
105 root 1.1 }
106    
107 root 1.9 our $current = $main;
108 root 1.19
109     sub current() { $current }
110 root 1.9
111     =item $idle
112    
113     The coroutine to switch to when no other coroutine is running. The default
114     implementation prints "FATAL: deadlock detected" and exits.
115    
116     =cut
117    
118     # should be done using priorities :(
119     our $idle = new Coro sub {
120     print STDERR "FATAL: deadlock detected\n";
121     exit(51);
122     };
123 root 1.8
124     # we really need priorities...
125 root 1.16 my @ready; # the ready queue. hehe, rather broken ;)
126 root 1.8
127     # static methods. not really.
128    
129     =head2 STATIC METHODS
130    
131     Static methods are actually functions that operate on the current process only.
132    
133     =over 4
134    
135 root 1.13 =item async { ... } [@args...]
136 root 1.8
137     Create a new asynchronous process and return it's process object
138     (usually unused). When the sub returns the new process is automatically
139     terminated.
140    
141 root 1.13 # create a new coroutine that just prints its arguments
142     async {
143     print "@_\n";
144     } 1,2,3,4;
145    
146     The coderef you submit MUST NOT be a closure that refers to variables
147     in an outer scope. This does NOT work. Pass arguments into it instead.
148    
149 root 1.8 =cut
150    
151 root 1.13 sub async(&@) {
152     my $pid = new Coro @_;
153 root 1.11 $pid->ready;
154     $pid;
155 root 1.8 }
156 root 1.1
157 root 1.8 =item schedule
158 root 1.6
159 root 1.8 Calls the scheduler. Please note that the current process will not be put
160     into the ready queue, so calling this function usually means you will
161     never be called again.
162 root 1.1
163     =cut
164    
165 root 1.8 my $prev;
166    
167     sub schedule {
168 root 1.9 # should be done using priorities :(
169     ($prev, $current) = ($current, shift @ready || $idle);
170 root 1.8 Coro::State::transfer($prev, $current);
171 root 1.1 }
172    
173 root 1.22 =item cede
174 root 1.1
175 root 1.22 "Cede" to other processes. This function puts the current process into the
176     ready queue and calls C<schedule>, which has the effect of giving up the
177     current "timeslice" to other coroutines of the same or higher priority.
178 root 1.7
179 root 1.8 =cut
180    
181 root 1.22 sub cede {
182 root 1.8 $current->ready;
183     &schedule;
184     }
185 root 1.7
186 root 1.8 =item terminate
187 root 1.7
188 root 1.8 Terminates the current process.
189 root 1.1
190 root 1.13 Future versions of this function will allow result arguments.
191    
192 root 1.1 =cut
193    
194 root 1.8 sub terminate {
195 root 1.22 my $self = $current;
196     $self->{_results} = [@_];
197     $current = shift @ready || $idle;
198     Coro::State::transfer(delete $self->{_coro_state}, $current);
199     # cannot return
200     die;
201 root 1.1 }
202 root 1.6
203 root 1.8 =back
204    
205     # dynamic methods
206    
207     =head2 PROCESS METHODS
208    
209     These are the methods you can call on process objects.
210 root 1.6
211 root 1.8 =over 4
212    
213 root 1.13 =item new Coro \&sub [, @args...]
214 root 1.8
215     Create a new process and return it. When the sub returns the process
216     automatically terminates. To start the process you must first put it into
217     the ready queue by calling the ready method.
218 root 1.6
219 root 1.13 The coderef you submit MUST NOT be a closure that refers to variables
220     in an outer scope. This does NOT work. Pass arguments into it instead.
221    
222 root 1.6 =cut
223    
224 root 1.13 sub _newcoro {
225     terminate &{+shift};
226     }
227    
228 root 1.8 sub new {
229     my $class = shift;
230     bless {
231 root 1.13 _coro_state => (new Coro::State $_[0] && \&_newcoro, @_),
232 root 1.8 }, $class;
233     }
234 root 1.6
235 root 1.8 =item $process->ready
236 root 1.1
237 root 1.8 Put the current process into the ready queue.
238 root 1.1
239 root 1.8 =cut
240 root 1.1
241 root 1.8 sub ready {
242     push @ready, $_[0];
243     }
244 root 1.1
245 root 1.8 =back
246 root 1.2
247 root 1.8 =cut
248 root 1.2
249 root 1.8 1;
250 root 1.14
251 root 1.17 =head1 BUGS/LIMITATIONS
252 root 1.14
253     - could be faster, especially when the core would introduce special
254     support for coroutines (like it does for threads).
255     - there is still a memleak on coroutine termination that I could not
256     identify. Could be as small as a single SV.
257     - this module is not well-tested.
258 root 1.17 - if variables or arguments "disappear" (become undef) or become
259     corrupted please contact the author so he cen iron out the
260     remaining bugs.
261     - this module is not thread-safe. You must only ever use this module from
262     the same thread (this requirement might be loosened in the future to
263 root 1.20 allow per-thread schedulers, but Coro::State does not yet allow this).
264 root 1.9
265     =head1 SEE ALSO
266    
267     L<Coro::Channel>, L<Coro::Cont>, L<Coro::Specific>, L<Coro::Semaphore>,
268 root 1.10 L<Coro::Signal>, L<Coro::State>, L<Coro::Event>.
269 root 1.1
270     =head1 AUTHOR
271    
272     Marc Lehmann <pcg@goof.com>
273     http://www.goof.com/pcg/marc/
274    
275     =cut
276