ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.38
Committed: Mon Nov 20 20:14:02 2006 UTC (17 years, 6 months ago) by root
Branch: MAIN
Changes since 1.37: +1 -18 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 Please note that even programs or modules (such as
38 L<Coro::Handle|Coro::Handle>) that use "traditional"
39 event-based/continuation style will run more efficient with this module
40 then when using only Event.
41
42 =over 4
43
44 =cut
45
46 package Coro::Event;
47
48 BEGIN { eval { require warnings } && warnings->unimport ("uninitialized") }
49
50 use Carp;
51 no warnings;
52
53 use Coro;
54 use Event qw(loop unloop); # we are re-exporting this, cooool!
55
56 use XSLoader;
57
58 use base Exporter::;
59
60 our @EXPORT = qw(loop unloop sweep reschedule);
61
62 BEGIN {
63 our $VERSION = 1.9;
64
65 local $^W = 0; # avoid redefine warning for Coro::ready;
66 XSLoader::load __PACKAGE__, $VERSION;
67 }
68
69 =item $w = Coro::Event->flavour(args...)
70
71 Create and return a watcher of the given type.
72
73 Examples:
74
75 my $reader = Coro::Event->io(fd => $filehandle, poll => 'r');
76 $reader->next;
77
78 =cut
79
80 =item $w->next
81
82 Return the next event of the event queue of the watcher.
83
84 =cut
85
86 =item do_flavour(args...)
87
88 Create a watcher of the given type and immediately call it's next
89 method. This is less efficient then calling the constructor once and the
90 next method often, but it does save typing sometimes.
91
92 =cut
93
94 for my $flavour (qw(idle var timer io signal)) {
95 push @EXPORT, "do_$flavour";
96 my $new = \&{"Event::$flavour"};
97 my $class = "Coro::Event::$flavour";
98 my $type = $flavour eq "io" ? 1 : 0;
99 @{"${class}::ISA"} = (Coro::Event::, "Event::$flavour");
100 my $coronew = sub {
101 # how does one do method-call-by-name?
102 # my $w = $class->SUPER::$flavour(@_);
103
104 shift eq Coro::Event::
105 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
106
107 my $w = $new->($class,
108 desc => $flavour,
109 @_,
110 parked => 1,
111 );
112 _install_std_cb($w, $type);
113 bless $w, $class; # reblessing due to broken Event
114 };
115 *{ $flavour } = $coronew;
116 *{"do_$flavour"} = sub {
117 unshift @_, Coro::Event::;
118 my $e = (&$coronew)->next;
119 $e->cancel; # $e === $e->w
120 $e;
121 };
122 }
123
124 # double calls to avoid stack-cloning ;()
125 # is about 10% slower, though.
126 sub next($) {
127 &Coro::schedule if &_next; $_[0];
128 }
129
130 sub Coro::Event::w { $_[0] }
131 sub Coro::Event::prio { $_[0]{Coro::Event}[3] }
132 sub Coro::Event::hits { $_[0]{Coro::Event}[4] }
133 sub Coro::Event::got { $_[0]{Coro::Event}[5] }
134
135 =item sweep
136
137 Similar to Event::one_event and Event::sweep: The idle task is called once
138 (this has the effect of jumping back into the Event loop once to serve new
139 events).
140
141 The reason this function exists is that you sometimes want to serve events
142 while doing other work. Calling C<Coro::cede> does not work because
143 C<cede> implies that the current coroutine is runnable and does not call
144 into the Event dispatcher.
145
146 =cut
147
148 sub sweep {
149 Event::one_event(0); # for now
150 }
151
152 =item $result = loop([$timeout])
153
154 This is the version of C<loop> you should use instead of C<Event::loop>
155 when using this module - it will ensure correct scheduling in the presence
156 of events.
157
158 =item unloop([$result])
159
160 Same as Event::unloop (provided here for your convinience only).
161
162 =cut
163
164 $Coro::idle = new Coro sub {
165 while () {
166 Coro::schedule;
167 Event::one_event; # inefficient
168 }
169 };
170
171 # provide hooks for Coro::Timer
172
173 package Coro::Timer;
174
175 unless ($override) {
176 $override = 1;
177 *_new_timer = sub {
178 Event->timer(at => $_[0], cb => $_[1]);
179 };
180 }
181
182 1;
183
184 =back
185
186 =head1 AUTHOR
187
188 Marc Lehmann <schmorp@schmorp.de>
189 http://home.schmorp.de/
190
191 =cut
192