ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro.pm
Revision: 1.12
Committed: Sun Jul 15 15:58:16 2001 UTC (22 years, 11 months ago) by root
Branch: MAIN
Changes since 1.11: +2 -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.05;
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 local @_;
135 # should be done using priorities :(
136 ($prev, $current) = ($current, shift @ready || $idle);
137 Coro::State::transfer($prev, $current);
138 }
139
140 =item yield
141
142 Yield to other processes. This function puts the current process into the
143 ready queue and calls C<schedule>.
144
145 =cut
146
147 sub yield {
148 $current->ready;
149 &schedule;
150 }
151
152 =item terminate
153
154 Terminates the current process.
155
156 =cut
157
158 sub terminate {
159 &schedule;
160 }
161
162 =back
163
164 # dynamic methods
165
166 =head2 PROCESS METHODS
167
168 These are the methods you can call on process objects.
169
170 =over 4
171
172 =item new Coro \&sub;
173
174 Create a new process and return it. When the sub returns the process
175 automatically terminates. To start the process you must first put it into
176 the ready queue by calling the ready method.
177
178 =cut
179
180 sub new {
181 my $class = shift;
182 my $proc = $_[0];
183 bless {
184 _coro_state => new Coro::State ($proc ? sub { &$proc; &terminate } : $proc),
185 }, $class;
186 }
187
188 =item $process->ready
189
190 Put the current process into the ready queue.
191
192 =cut
193
194 sub ready {
195 push @ready, $_[0];
196 }
197
198 =back
199
200 =cut
201
202 1;
203
204 =head1 SEE ALSO
205
206 L<Coro::Channel>, L<Coro::Cont>, L<Coro::Specific>, L<Coro::Semaphore>,
207 L<Coro::Signal>, L<Coro::State>, L<Coro::Event>.
208
209 =head1 AUTHOR
210
211 Marc Lehmann <pcg@goof.com>
212 http://www.goof.com/pcg/marc/
213
214 =cut
215