ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.7
Committed: Tue Oct 9 00:50:32 2001 UTC (22 years, 8 months ago) by root
Branch: MAIN
Changes since 1.6: +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     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 root 1.6 no warnings qw(uninitialized);
44 root 1.1
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 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.4 $e->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     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