ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.6
Committed: Mon Sep 24 01:36:20 2001 UTC (22 years, 8 months ago) by root
Branch: MAIN
Changes since 1.5: +2 -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->main.
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(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.45;
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 $_[0] eq Coro::Event::
98 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
99
100 my $q = []; # [$coro, $event]
101 my $w = $new->(
102 desc => $flavour,
103 @_,
104 parked => 1,
105 );
106 _install_std_cb($w, $type);
107 bless $w, $class; # reblessing due to broken Event
108 };
109 *{ $flavour } = $coronew;
110 *{"do_$flavour"} = sub {
111 unshift @_, Coro::Event::;
112 my $e = (&$coronew)->next;
113 $e->cancel; # $e = $e->w
114 $e;
115 };
116 }
117
118 # double calls to avoid stack-cloning ;()
119 # is about 10% slower, though.
120 sub next($) {
121 &Coro::schedule if &_next; $_[0];
122 }
123
124 sub Coro::Event::w { $_[0] }
125 sub Coro::Event::prio { $_[0]{Coro::Event}[3] }
126 sub Coro::Event::hits { $_[0]{Coro::Event}[4] }
127 sub Coro::Event::got { $_[0]{Coro::Event}[5] }
128
129 =item sweep
130
131 Similar to Event::one_event and Event::sweep: The idle task is called once
132 (this has the effect of jumping back into the Event loop once to serve new
133 events).
134
135 The reason this function exists is that you sometimes want to serve events
136 while doing other work. Calling C<Coro::cede> does not work because
137 C<cede> implies that the current coroutine is runnable and does not call
138 into the Event dispatcher.
139
140 =cut
141
142 sub sweep {
143 one_event(0); # for now
144 }
145
146 =item $result = loop([$timeout])
147
148 This is the version of C<loop> you should use instead of C<Event::loop>
149 when using this module - it will ensure correct scheduling in the presence
150 of events.
151
152 =begin comment
153
154 Unlike loop's counterpart it is not an error when no watchers are active -
155 loop silently returns in this case, as if unloop(undef) were called.
156
157 =end comment
158
159 =cut
160
161 sub loop(;$) {
162 local $Coro::idle = $Coro::current;
163 Coro::schedule; # become idle task, which is implicitly ready
164 &Event::loop;
165 }
166
167 =item unloop([$result])
168
169 Same as Event::unloop (provided here for your convinience only).
170
171 =cut
172
173 $Coro::idle = new Coro sub {
174 while () {
175 Event::one_event; # inefficient
176 Coro::schedule;
177 }
178 };
179
180 1;
181
182 =head1 AUTHOR
183
184 Marc Lehmann <pcg@goof.com>
185 http://www.goof.com/pcg/marc/
186
187 =cut
188