ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.35
Committed: Wed Feb 1 23:59:41 2006 UTC (18 years, 4 months ago) by root
Branch: MAIN
CVS Tags: rel-2_0, rel-1_9
Changes since 1.34: +1 -1 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     =over 4
38    
39     =cut
40    
41     package Coro::Event;
42    
43 pcg 1.18 BEGIN { eval { require warnings } && warnings->unimport ("uninitialized") }
44 root 1.1
45     use Carp;
46 root 1.30 no warnings;
47 root 1.1
48     use Coro;
49 root 1.8 use Event qw(loop unloop); # we are re-exporting this, cooool!
50 root 1.1
51 root 1.30 use XSLoader;
52 root 1.1
53 root 1.30 use base Exporter::;
54    
55     our @EXPORT = qw(loop unloop sweep reschedule);
56 root 1.1
57 root 1.2 BEGIN {
58 root 1.35 our $VERSION = 1.9;
59 root 1.2
60 root 1.13 local $^W = 0; # avoid redefine warning for Coro::ready;
61 root 1.30 XSLoader::load __PACKAGE__, $VERSION;
62 root 1.2 }
63 root 1.1
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 root 1.2 my $type = $flavour eq "io" ? 1 : 0;
94 root 1.1 @{"${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 root 1.10 shift eq Coro::Event::
100 root 1.1 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
101    
102 root 1.10 my $w = $new->($class,
103 root 1.1 desc => $flavour,
104     @_,
105 root 1.2 parked => 1,
106 root 1.1 );
107 root 1.2 _install_std_cb($w, $type);
108 root 1.1 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 pcg 1.20 $e->cancel; # $e === $e->w
115 root 1.1 $e;
116     };
117     }
118    
119 root 1.2 # double calls to avoid stack-cloning ;()
120 root 1.3 # is about 10% slower, though.
121 root 1.2 sub next($) {
122 root 1.3 &Coro::schedule if &_next; $_[0];
123 root 1.1 }
124 root 1.2
125 root 1.4 sub Coro::Event::w { $_[0] }
126 root 1.5 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 root 1.1
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 root 1.7 Event::one_event(0); # for now
145 root 1.1 }
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 root 1.8 # 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 root 1.1
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 root 1.9 # 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 root 1.1 1;
195    
196     =head1 AUTHOR
197    
198 root 1.27 Marc Lehmann <schmorp@schmorp.de>
199 root 1.25 http://home.schmorp.de/
200 root 1.1
201     =cut
202