ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/Event.pm
Revision: 1.23
Committed: Thu Aug 16 21:55:34 2001 UTC (22 years, 9 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.22: +0 -0 lines
State: FILE REMOVED
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 root 1.3 unloop unless $cmd ne "";
16 root 1.1 print "data> ";
17     my $ev = $w->next; my $data = <STDIN>;
18     }
19     }
20    
21 root 1.3 &loop;
22    
23 root 1.1 =head1 DESCRIPTION
24    
25 root 1.12 This module enables you to create programs using the powerful Event model
26 root 1.1 (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;
44    
45 root 1.3 use Carp;
46    
47 root 1.12 use Coro;
48 root 1.3 use Event qw(unloop); # we are re-exporting this, cooool!
49 root 1.1
50     use base 'Exporter';
51    
52 root 1.9 @EXPORT = qw(loop unloop sweep);
53 root 1.3
54 root 1.20 $VERSION = 0.45;
55 root 1.1
56 root 1.3 =item $w = Coro::Event->flavour(args...)
57 root 1.1
58     Create and return a watcher of the given type.
59    
60     Examples:
61    
62     my $reader = Coro::Event->io(fd => $filehandle, poll => 'r');
63     $reader->next;
64    
65     =cut
66    
67 root 1.3 =item $w->next
68    
69     Return the next event of the event queue of the watcher.
70    
71     =cut
72    
73 root 1.1 =item do_flavour(args...)
74    
75     Create a watcher of the given type and immediately call it's next
76     method. This is less efficient then calling the constructor once and the
77     next method often, but it does save typing sometimes.
78    
79     =cut
80    
81 root 1.22 Event->add_hooks(prepare => sub {
82     &Coro::cede while &Coro::nready;
83     1e6;
84     });
85    
86 root 1.13 sub std_cb {
87     my $w = $_[0]->w;
88     my $q = $w->private;
89     $q->[1] = $_[0];
90     if ($q->[0]) { # somebody waiting?
91     $q->[0]->ready;
92     } else {
93     $w->stop;
94     }
95     }
96    
97 root 1.1 for my $flavour (qw(idle var timer io signal)) {
98     push @EXPORT, "do_$flavour";
99     my $new = \&{"Event::$flavour"};
100     my $class = "Coro::Event::$flavour";
101 root 1.13 @{"${class}::ISA"} = (Coro::Event::, "Event::$flavour");
102 root 1.1 my $coronew = sub {
103     # how does one do method-call-by-name?
104     # my $w = $class->SUPER::$flavour(@_);
105    
106 root 1.9 $_[0] eq Coro::Event::
107     or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
108    
109 root 1.3 my $q = []; # [$coro, $event]
110 root 1.17 my $w = $new->(
111     desc => $flavour,
112     @_,
113     cb => \&std_cb,
114     );
115 root 1.1 $w->private($q); # using private as attribute is pretty useless...
116     bless $w, $class; # reblessing due to broken Event
117     };
118     *{ $flavour } = $coronew;
119     *{"do_$flavour"} = sub {
120 root 1.11 unshift @_, Coro::Event::;
121 root 1.17 my $e = (&$coronew)->next;
122     $e->w->cancel;
123     $e;
124 root 1.1 };
125     }
126    
127 root 1.3 sub next {
128 root 1.13 my $w = $_[0];
129     my $q = $w->private;
130     if ($q->[1]) { # event waiting?
131     $w->again unless $w->is_cancelled;
132     } elsif ($q->[0]) {
133     croak "only one coroutine can wait for an event";
134     } else {
135 root 1.3 local $q->[0] = $Coro::current;
136 root 1.21 &Coro::schedule;
137 root 1.3 }
138 root 1.19 pop @$q;
139 root 1.3 }
140    
141 root 1.9 =item sweep
142 root 1.7
143     Similar to Event::one_event and Event::sweep: The idle task is called once
144     (this has the effect of jumping back into the Event loop once to serve new
145     events).
146    
147 root 1.10 The reason this function exists is that you sometimes want to serve events
148 root 1.13 while doing other work. Calling C<Coro::cede> does not work because
149     C<cede> implies that the current coroutine is runnable and does not call
150 root 1.10 into the Event dispatcher.
151    
152 root 1.7 =cut
153    
154 root 1.9 sub sweep {
155 root 1.16 one_event(0); # for now
156 root 1.7 }
157    
158 root 1.3 =item $result = loop([$timeout])
159 root 1.1
160 root 1.3 This is the version of C<loop> you should use instead of C<Event::loop>
161     when using this module - it will ensure correct scheduling in the presence
162     of events.
163 root 1.1
164 root 1.18 =begin comment
165    
166     Unlike loop's counterpart it is not an error when no watchers are active -
167     loop silently returns in this case, as if unloop(undef) were called.
168    
169     =end comment
170    
171 root 1.1 =cut
172    
173 root 1.3 sub loop(;$) {
174     local $Coro::idle = $Coro::current;
175     Coro::schedule; # become idle task, which is implicitly ready
176     &Event::loop;
177 root 1.1 }
178    
179 root 1.3 =item unloop([$result])
180    
181     Same as Event::unloop (provided here for your convinience only).
182 root 1.1
183     =cut
184 root 1.7
185     $Coro::idle = new Coro sub {
186 root 1.12 while () {
187     Event::one_event; # inefficient
188     Coro::schedule;
189     }
190 root 1.7 };
191 root 1.1
192     1;
193    
194     =head1 AUTHOR
195    
196     Marc Lehmann <pcg@goof.com>
197     http://www.goof.com/pcg/marc/
198    
199     =cut
200