ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.37
Committed: Mon Nov 20 19:56:04 2006 UTC (17 years, 7 months ago) by root
Branch: MAIN
Changes since 1.36: +5 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.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 pcg 1.21 my $w = Coro::Event->io(fd => \*STDIN, poll => 'r');
12 root 1.1 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 root 1.8 loop;
22 root 1.1
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 root 1.12 Coro::Event::loop.
36 root 1.1
37 root 1.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 root 1.1 =over 4
43    
44     =cut
45    
46     package Coro::Event;
47    
48 pcg 1.18 BEGIN { eval { require warnings } && warnings->unimport ("uninitialized") }
49 root 1.1
50     use Carp;
51 root 1.30 no warnings;
52 root 1.1
53     use Coro;
54 root 1.8 use Event qw(loop unloop); # we are re-exporting this, cooool!
55 root 1.1
56 root 1.30 use XSLoader;
57 root 1.1
58 root 1.30 use base Exporter::;
59    
60     our @EXPORT = qw(loop unloop sweep reschedule);
61 root 1.1
62 root 1.2 BEGIN {
63 root 1.35 our $VERSION = 1.9;
64 root 1.2
65 root 1.13 local $^W = 0; # avoid redefine warning for Coro::ready;
66 root 1.30 XSLoader::load __PACKAGE__, $VERSION;
67 root 1.2 }
68 root 1.1
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 root 1.2 my $type = $flavour eq "io" ? 1 : 0;
99 root 1.1 @{"${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 root 1.10 shift eq Coro::Event::
105 root 1.1 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
106    
107 root 1.10 my $w = $new->($class,
108 root 1.1 desc => $flavour,
109     @_,
110 root 1.2 parked => 1,
111 root 1.1 );
112 root 1.2 _install_std_cb($w, $type);
113 root 1.1 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 pcg 1.20 $e->cancel; # $e === $e->w
120 root 1.1 $e;
121     };
122     }
123    
124 root 1.2 # double calls to avoid stack-cloning ;()
125 root 1.3 # is about 10% slower, though.
126 root 1.2 sub next($) {
127 root 1.3 &Coro::schedule if &_next; $_[0];
128 root 1.1 }
129 root 1.2
130 root 1.4 sub Coro::Event::w { $_[0] }
131 root 1.5 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 root 1.1
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 root 1.7 Event::one_event(0); # for now
150 root 1.1 }
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     =begin comment
159    
160     Unlike loop's counterpart it is not an error when no watchers are active -
161     loop silently returns in this case, as if unloop(undef) were called.
162    
163     =end comment
164    
165     =cut
166    
167 root 1.8 # no longer do something special - it's done internally now
168    
169     #sub loop(;$) {
170     # #local $Coro::idle = $Coro::current;
171     # #Coro::schedule; # become idle task, which is implicitly ready
172     # &Event::loop;
173     #}
174 root 1.1
175     =item unloop([$result])
176    
177     Same as Event::unloop (provided here for your convinience only).
178    
179     =cut
180    
181     $Coro::idle = new Coro sub {
182     while () {
183     Event::one_event; # inefficient
184     Coro::schedule;
185     }
186     };
187    
188 root 1.9 # provide hooks for Coro::Timer
189    
190     package Coro::Timer;
191    
192     unless ($override) {
193     $override = 1;
194     *_new_timer = sub {
195     Event->timer(at => $_[0], cb => $_[1]);
196     };
197     }
198    
199 root 1.1 1;
200    
201 root 1.36 =back
202    
203 root 1.1 =head1 AUTHOR
204    
205 root 1.27 Marc Lehmann <schmorp@schmorp.de>
206 root 1.25 http://home.schmorp.de/
207 root 1.1
208     =cut
209