ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.9
Committed: Tue Nov 27 02:59:37 2001 UTC (22 years, 7 months ago) by root
Branch: MAIN
Changes since 1.8: +11 -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     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 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     Coro::Event->main.
36    
37     =over 4
38    
39     =cut
40    
41     package Coro::Event;
42    
43 root 1.6 no warnings qw(uninitialized);
44 root 1.1
45     use Carp;
46    
47     use Coro;
48 root 1.8 use Event qw(loop unloop); # we are re-exporting this, cooool!
49 root 1.1
50     use base 'Exporter';
51    
52 root 1.5 @EXPORT = qw(loop unloop sweep reschedule);
53 root 1.1
54 root 1.2 BEGIN {
55     $VERSION = 0.45;
56    
57 root 1.6 local $^W = 0; # avoid redefine warning for Coro::ready
58 root 1.2 require XSLoader;
59     XSLoader::load Coro::Event, $VERSION;
60     }
61 root 1.1
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 root 1.2 my $type = $flavour eq "io" ? 1 : 0;
92 root 1.1 @{"${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 root 1.2 parked => 1,
105 root 1.1 );
106 root 1.2 _install_std_cb($w, $type);
107 root 1.1 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 root 1.8 $e->cancel; # $e = $e->w->cancel ($e == $e->w!)
114 root 1.1 $e;
115     };
116     }
117    
118 root 1.2 # double calls to avoid stack-cloning ;()
119 root 1.3 # is about 10% slower, though.
120 root 1.2 sub next($) {
121 root 1.3 &Coro::schedule if &_next; $_[0];
122 root 1.1 }
123 root 1.2
124 root 1.4 sub Coro::Event::w { $_[0] }
125 root 1.5 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 root 1.1
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 root 1.7 Event::one_event(0); # for now
144 root 1.1 }
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 root 1.8 # no longer do something special - it's done internally now
162    
163     #sub loop(;$) {
164     # #local $Coro::idle = $Coro::current;
165     # #Coro::schedule; # become idle task, which is implicitly ready
166     # &Event::loop;
167     #}
168 root 1.1
169     =item unloop([$result])
170    
171     Same as Event::unloop (provided here for your convinience only).
172    
173     =cut
174    
175     $Coro::idle = new Coro sub {
176     while () {
177     Event::one_event; # inefficient
178     Coro::schedule;
179     }
180     };
181    
182 root 1.9 # provide hooks for Coro::Timer
183    
184     package Coro::Timer;
185    
186     unless ($override) {
187     $override = 1;
188     *_new_timer = sub {
189     Event->timer(at => $_[0], cb => $_[1]);
190     };
191     }
192    
193 root 1.1 1;
194    
195     =head1 AUTHOR
196    
197     Marc Lehmann <pcg@goof.com>
198     http://www.goof.com/pcg/marc/
199    
200     =cut
201