ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.14
Committed: Sat Mar 22 23:08:41 2003 UTC (21 years, 2 months ago) by root
Branch: MAIN
Changes since 1.13: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Coro::Event - do events the coro-way
4
5 =head1 SYNOPSIS
6
7 use Coro;
8 use Coro::Event;
9
10 sub keyboard : Coro {
11 my $w = Coro::Event->io(fd => *STDIN, poll => 'r');
12 while() {
13 print "cmd> ";
14 my $ev = $w->next; my $cmd = <STDIN>;
15 unloop unless $cmd ne "";
16 print "data> ";
17 my $ev = $w->next; my $data = <STDIN>;
18 }
19 }
20
21 loop;
22
23 =head1 DESCRIPTION
24
25 This module enables you to create programs using the powerful Event model
26 (and module), while retaining the linear style known from simple or
27 threaded programs.
28
29 This module provides a method and a function for every watcher type
30 (I<flavour>) (see L<Event>). The only difference between these and the
31 watcher constructors from Event is that you do not specify a callback
32 function - it will be managed by this module.
33
34 Your application should just create all necessary coroutines and then call
35 Coro::Event::loop.
36
37 =over 4
38
39 =cut
40
41 package Coro::Event;
42
43 no warnings qw(uninitialized);
44
45 use Carp;
46
47 use Coro;
48 use Event qw(loop unloop); # we are re-exporting this, cooool!
49
50 use base 'Exporter';
51
52 @EXPORT = qw(loop unloop sweep reschedule);
53
54 BEGIN {
55 $VERSION = 0.65;
56
57 local $^W = 0; # avoid redefine warning for Coro::ready;
58 require XSLoader;
59 XSLoader::load Coro::Event, $VERSION;
60 }
61
62 =item $w = Coro::Event->flavour(args...)
63
64 Create and return a watcher of the given type.
65
66 Examples:
67
68 my $reader = Coro::Event->io(fd => $filehandle, poll => 'r');
69 $reader->next;
70
71 =cut
72
73 =item $w->next
74
75 Return the next event of the event queue of the watcher.
76
77 =cut
78
79 =item do_flavour(args...)
80
81 Create a watcher of the given type and immediately call it's next
82 method. This is less efficient then calling the constructor once and the
83 next method often, but it does save typing sometimes.
84
85 =cut
86
87 for my $flavour (qw(idle var timer io signal)) {
88 push @EXPORT, "do_$flavour";
89 my $new = \&{"Event::$flavour"};
90 my $class = "Coro::Event::$flavour";
91 my $type = $flavour eq "io" ? 1 : 0;
92 @{"${class}::ISA"} = (Coro::Event::, "Event::$flavour");
93 my $coronew = sub {
94 # how does one do method-call-by-name?
95 # my $w = $class->SUPER::$flavour(@_);
96
97 shift eq Coro::Event::
98 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
99
100 my $w = $new->($class,
101 desc => $flavour,
102 @_,
103 parked => 1,
104 );
105 _install_std_cb($w, $type);
106 bless $w, $class; # reblessing due to broken Event
107 };
108 *{ $flavour } = $coronew;
109 *{"do_$flavour"} = sub {
110 unshift @_, Coro::Event::;
111 my $e = (&$coronew)->next;
112 $e->cancel; # $e = $e->w->cancel ($e == $e->w!)
113 $e;
114 };
115 }
116
117 # double calls to avoid stack-cloning ;()
118 # is about 10% slower, though.
119 sub next($) {
120 &Coro::schedule if &_next; $_[0];
121 }
122
123 sub Coro::Event::w { $_[0] }
124 sub Coro::Event::prio { $_[0]{Coro::Event}[3] }
125 sub Coro::Event::hits { $_[0]{Coro::Event}[4] }
126 sub Coro::Event::got { $_[0]{Coro::Event}[5] }
127
128 =item sweep
129
130 Similar to Event::one_event and Event::sweep: The idle task is called once
131 (this has the effect of jumping back into the Event loop once to serve new
132 events).
133
134 The reason this function exists is that you sometimes want to serve events
135 while doing other work. Calling C<Coro::cede> does not work because
136 C<cede> implies that the current coroutine is runnable and does not call
137 into the Event dispatcher.
138
139 =cut
140
141 sub sweep {
142 Event::one_event(0); # for now
143 }
144
145 =item $result = loop([$timeout])
146
147 This is the version of C<loop> you should use instead of C<Event::loop>
148 when using this module - it will ensure correct scheduling in the presence
149 of events.
150
151 =begin comment
152
153 Unlike loop's counterpart it is not an error when no watchers are active -
154 loop silently returns in this case, as if unloop(undef) were called.
155
156 =end comment
157
158 =cut
159
160 # no longer do something special - it's done internally now
161
162 #sub loop(;$) {
163 # #local $Coro::idle = $Coro::current;
164 # #Coro::schedule; # become idle task, which is implicitly ready
165 # &Event::loop;
166 #}
167
168 =item unloop([$result])
169
170 Same as Event::unloop (provided here for your convinience only).
171
172 =cut
173
174 $Coro::idle = new Coro sub {
175 while () {
176 Event::one_event; # inefficient
177 Coro::schedule;
178 }
179 };
180
181 # provide hooks for Coro::Timer
182
183 package Coro::Timer;
184
185 unless ($override) {
186 $override = 1;
187 *_new_timer = sub {
188 Event->timer(at => $_[0], cb => $_[1]);
189 };
190 }
191
192 1;
193
194 =head1 AUTHOR
195
196 Marc Lehmann <pcg@goof.com>
197 http://www.goof.com/pcg/marc/
198
199 =cut
200