ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/State.pm
Revision: 1.5
Committed: Thu Jul 19 02:45:09 2001 UTC (22 years, 10 months ago) by root
Branch: MAIN
Changes since 1.4: +35 -8 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Coro::State - create and manage simple coroutines
4
5 =head1 SYNOPSIS
6
7 use Coro::State;
8
9 $new = new Coro::State sub {
10 print "in coroutine (called with @_), switching back\n";
11 $new->transfer($main);
12 print "in coroutine again, switching back\n";
13 $new->transfer($main);
14 }, 5;
15
16 $main = new Coro::State;
17
18 print "in main, switching to coroutine\n";
19 $main->transfer($new);
20 print "back in main, switch to coroutine again\n";
21 $main->transfer($new);
22 print "back in main\n";
23
24 =head1 DESCRIPTION
25
26 This module implements coroutines. Coroutines, similar to continuations,
27 allow you to run more than one "thread of execution" in parallel. Unlike
28 threads this, only voluntary switching is used so locking problems are
29 greatly reduced.
30
31 This module provides only low-level functionality. See L<Coro> and related
32 modules for a more useful process abstraction including scheduling.
33
34 =over 4
35
36 =cut
37
38 package Coro::State;
39
40 BEGIN {
41 $VERSION = 0.08;
42
43 require XSLoader;
44 XSLoader::load Coro::State, $VERSION;
45 }
46
47 use base 'Exporter';
48
49 @EXPORT_OK = qw(SAVE_DEFAV SAVE_DEFSV SAVE_ERRSV);
50
51 =item $coro = new [$coderef] [, @args...]
52
53 Create a new coroutine and return it. The first C<transfer> call to this
54 coroutine will start execution at the given coderef. If, the subroutine
55 returns it will be executed again.
56
57 The coderef you submit MUST NOT be a closure that refers to variables
58 in an outer scope. This does NOT work.
59
60 If the coderef is omitted this function will create a new "empty"
61 coroutine, i.e. a coroutine that cannot be transfered to but can be used
62 to save the current coroutine in.
63
64 =cut
65
66 sub _newcoro {
67 my $proc = shift;
68 do {
69 eval { &$proc };
70 if ($@) {
71 my $err = $@;
72 $error->(undef, $err);
73 print STDERR "FATAL: error function returned\n";
74 exit(50);
75 }
76 } while (1);
77 }
78
79 sub new {
80 my $class = shift;
81 my $proc = shift || sub { die "tried to transfer to an empty coroutine" };
82 bless _newprocess [$proc, @_], $class;
83 }
84
85 =item $prev->transfer($next,[$flags])
86
87 Save the state of the current subroutine in C<$prev> and switch to the
88 coroutine saved in C<$next>.
89
90 The "state" of a subroutine includes the scope, i.e. lexical variables and
91 the current execution state. The C<$flags> value can be used to specify
92 that additional state be saved/restored, by C<||>-ing the following
93 constants together:
94
95 Constant Effect
96 SAVE_DEFAV save/restore @_
97 SAVE_DEFSV save/restore $_
98 SAVE_ERRSV save/restore $@
99
100 These constants are not exported by default. The default is subject to
101 change (because we are still at an early development stage) but will
102 stabilize. You have to make sure that the destination state is valid with
103 respect to the flags, segfaults or worse will result otherwise.
104
105 If you feel that something important is missing then tell me. Also
106 remember that every function call that might call C<transfer> (such
107 as C<Coro::Channel::put>) might clobber any global and/or special
108 variables. Yes, this is by design ;) You can always create your own
109 process abstraction model that saves these variables.
110
111 The easiest way to do this is to create your own scheduling primitive like this:
112
113 sub schedule {
114 local ($_, $@, ...);
115 $old->transfer($new);
116 }
117
118 IMPLEMENTORS NOTE: all Coro::State functions/methods expect either the
119 usual Coro::State object or a hashref with a key named "_coro_state" that
120 contains the real Coro::State object. That is, you can do:
121
122 $obj->{_coro_state} = new Coro::State ...;
123 Coro::State::transfer(..., $obj);
124
125 This exists mainly to ease subclassing (wether through @ISA or not).
126
127 =cut
128
129 =item $error->($error_coro, $error_msg)
130
131 This function will be called on fatal errors. C<$error_msg> and
132 C<$error_coro> return the error message and the error-causing coroutine
133 (NOT an object) respectively. This API might change.
134
135 =cut
136
137 $error = sub {
138 require Carp;
139 Carp::confess("FATAL: $_[1]\n");
140 };
141
142 =item Coro::State::flush
143
144 To be efficient (actually, to not be abysmaly slow), this module does
145 some fair amount of caching (a possibly complex structure for every
146 subroutine in use). If you don't use coroutines anymore or you want to
147 reclaim some memory then you can call this function which will flush all
148 internal caches. The caches will be rebuilt when needed so this is a safe
149 operation.
150
151 =cut
152
153 1;
154
155 =back
156
157 =head1 BUGS
158
159 This module has not yet been extensively tested. Expect segfaults and
160 specially memleaks.
161
162 This module is not thread-safe. You must only ever use this module from
163 the same thread (this requirenmnt might be loosened in the future).
164
165 =head1 SEE ALSO
166
167 L<Coro>.
168
169 =head1 AUTHOR
170
171 Marc Lehmann <pcg@goof.com>
172 http://www.goof.com/pcg/marc/
173
174 =cut
175