ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.25
Committed: Wed Jan 12 20:35:35 2005 UTC (19 years, 4 months ago) by root
Branch: MAIN
Changes since 1.24: +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 BEGIN { eval { require warnings } && warnings->unimport ("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 = 1.0;
56
57 local $^W = 0; # avoid redefine warning for Coro::ready;
58
59 require DynaLoader;
60 push @ISA, 'DynaLoader';
61 bootstrap Coro::Event $VERSION;
62 }
63
64 =item $w = Coro::Event->flavour(args...)
65
66 Create and return a watcher of the given type.
67
68 Examples:
69
70 my $reader = Coro::Event->io(fd => $filehandle, poll => 'r');
71 $reader->next;
72
73 =cut
74
75 =item $w->next
76
77 Return the next event of the event queue of the watcher.
78
79 =cut
80
81 =item do_flavour(args...)
82
83 Create a watcher of the given type and immediately call it's next
84 method. This is less efficient then calling the constructor once and the
85 next method often, but it does save typing sometimes.
86
87 =cut
88
89 for my $flavour (qw(idle var timer io signal)) {
90 push @EXPORT, "do_$flavour";
91 my $new = \&{"Event::$flavour"};
92 my $class = "Coro::Event::$flavour";
93 my $type = $flavour eq "io" ? 1 : 0;
94 @{"${class}::ISA"} = (Coro::Event::, "Event::$flavour");
95 my $coronew = sub {
96 # how does one do method-call-by-name?
97 # my $w = $class->SUPER::$flavour(@_);
98
99 shift eq Coro::Event::
100 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
101
102 my $w = $new->($class,
103 desc => $flavour,
104 @_,
105 parked => 1,
106 );
107 _install_std_cb($w, $type);
108 bless $w, $class; # reblessing due to broken Event
109 };
110 *{ $flavour } = $coronew;
111 *{"do_$flavour"} = sub {
112 unshift @_, Coro::Event::;
113 my $e = (&$coronew)->next;
114 $e->cancel; # $e === $e->w
115 $e;
116 };
117 }
118
119 # double calls to avoid stack-cloning ;()
120 # is about 10% slower, though.
121 sub next($) {
122 &Coro::schedule if &_next; $_[0];
123 }
124
125 sub Coro::Event::w { $_[0] }
126 sub Coro::Event::prio { $_[0]{Coro::Event}[3] }
127 sub Coro::Event::hits { $_[0]{Coro::Event}[4] }
128 sub Coro::Event::got { $_[0]{Coro::Event}[5] }
129
130 =item sweep
131
132 Similar to Event::one_event and Event::sweep: The idle task is called once
133 (this has the effect of jumping back into the Event loop once to serve new
134 events).
135
136 The reason this function exists is that you sometimes want to serve events
137 while doing other work. Calling C<Coro::cede> does not work because
138 C<cede> implies that the current coroutine is runnable and does not call
139 into the Event dispatcher.
140
141 =cut
142
143 sub sweep {
144 Event::one_event(0); # for now
145 }
146
147 =item $result = loop([$timeout])
148
149 This is the version of C<loop> you should use instead of C<Event::loop>
150 when using this module - it will ensure correct scheduling in the presence
151 of events.
152
153 =begin comment
154
155 Unlike loop's counterpart it is not an error when no watchers are active -
156 loop silently returns in this case, as if unloop(undef) were called.
157
158 =end comment
159
160 =cut
161
162 # no longer do something special - it's done internally now
163
164 #sub loop(;$) {
165 # #local $Coro::idle = $Coro::current;
166 # #Coro::schedule; # become idle task, which is implicitly ready
167 # &Event::loop;
168 #}
169
170 =item unloop([$result])
171
172 Same as Event::unloop (provided here for your convinience only).
173
174 =cut
175
176 $Coro::idle = new Coro sub {
177 while () {
178 Event::one_event; # inefficient
179 Coro::schedule;
180 }
181 };
182
183 # provide hooks for Coro::Timer
184
185 package Coro::Timer;
186
187 unless ($override) {
188 $override = 1;
189 *_new_timer = sub {
190 Event->timer(at => $_[0], cb => $_[1]);
191 };
192 }
193
194 1;
195
196 =head1 AUTHOR
197
198 Marc Lehmann <pcg@goof.com>
199 http://home.schmorp.de/
200
201 =cut
202