ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.44
Committed: Fri Dec 1 20:49:54 2006 UTC (17 years, 7 months ago) by root
Branch: MAIN
CVS Tags: rel-3_1, rel-3_2, rel-3_0, rel-3_01, rel-3_11
Changes since 1.43: +6 -5 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.42 =head1 WARNING
43    
44     Please note that Event does not support coroutines or threads. That
45     means that you B<MUST NOT> block in an event callback. Again: In Event
46     callbacks, you I<must never ever> call a Coroutine fucntion that blocks
47     the current coroutine.
48    
49     While this seems to work superficially, it will eventually cause memory
50     corruption.
51    
52     =head1 FUNCTIONS
53    
54 root 1.1 =over 4
55    
56     =cut
57    
58     package Coro::Event;
59    
60 root 1.42 no warnings;
61 root 1.1
62     use Carp;
63 root 1.30 no warnings;
64 root 1.1
65     use Coro;
66 root 1.40 use Coro::Timer;
67 root 1.8 use Event qw(loop unloop); # we are re-exporting this, cooool!
68 root 1.1
69 root 1.30 use XSLoader;
70 root 1.1
71 root 1.30 use base Exporter::;
72    
73 root 1.41 our @EXPORT = qw(loop unloop sweep);
74 root 1.1
75 root 1.2 BEGIN {
76 root 1.35 our $VERSION = 1.9;
77 root 1.2
78 root 1.13 local $^W = 0; # avoid redefine warning for Coro::ready;
79 root 1.30 XSLoader::load __PACKAGE__, $VERSION;
80 root 1.2 }
81 root 1.1
82 root 1.42 =item $w = Coro::Event->flavour (args...)
83 root 1.1
84     Create and return a watcher of the given type.
85    
86     Examples:
87    
88     my $reader = Coro::Event->io(fd => $filehandle, poll => 'r');
89     $reader->next;
90    
91     =cut
92    
93     =item $w->next
94    
95     Return the next event of the event queue of the watcher.
96    
97     =cut
98    
99 root 1.42 =item do_flavour args...
100 root 1.1
101     Create a watcher of the given type and immediately call it's next
102     method. This is less efficient then calling the constructor once and the
103     next method often, but it does save typing sometimes.
104    
105     =cut
106    
107     for my $flavour (qw(idle var timer io signal)) {
108     push @EXPORT, "do_$flavour";
109     my $new = \&{"Event::$flavour"};
110     my $class = "Coro::Event::$flavour";
111 root 1.2 my $type = $flavour eq "io" ? 1 : 0;
112 root 1.1 @{"${class}::ISA"} = (Coro::Event::, "Event::$flavour");
113     my $coronew = sub {
114     # how does one do method-call-by-name?
115     # my $w = $class->SUPER::$flavour(@_);
116    
117 root 1.10 shift eq Coro::Event::
118 root 1.1 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
119    
120 root 1.10 my $w = $new->($class,
121 root 1.43 desc => $flavour,
122 root 1.1 @_,
123 root 1.2 parked => 1,
124 root 1.1 );
125 root 1.43
126     _install_std_cb $w, $type;
127    
128     # reblessing due to Event being broken
129     bless $w, $class
130 root 1.1 };
131     *{ $flavour } = $coronew;
132     *{"do_$flavour"} = sub {
133     unshift @_, Coro::Event::;
134 root 1.44 @_ = &$coronew;
135     &Coro::schedule while &_next;
136     $_[0]->cancel;
137     &_event
138 root 1.1 };
139     }
140    
141 root 1.44 # do schedule in perl to avoid forcing a stack allocation.
142 root 1.43 # this is about 10% slower, though.
143 root 1.2 sub next($) {
144 root 1.41 &Coro::schedule while &_next;
145    
146 root 1.44 &_event
147 root 1.1 }
148 root 1.2
149 root 1.4 sub Coro::Event::w { $_[0] }
150 root 1.5 sub Coro::Event::prio { $_[0]{Coro::Event}[3] }
151     sub Coro::Event::hits { $_[0]{Coro::Event}[4] }
152     sub Coro::Event::got { $_[0]{Coro::Event}[5] }
153 root 1.1
154     =item sweep
155    
156     Similar to Event::one_event and Event::sweep: The idle task is called once
157     (this has the effect of jumping back into the Event loop once to serve new
158     events).
159    
160     The reason this function exists is that you sometimes want to serve events
161     while doing other work. Calling C<Coro::cede> does not work because
162     C<cede> implies that the current coroutine is runnable and does not call
163     into the Event dispatcher.
164    
165     =cut
166    
167     sub sweep {
168 root 1.42 Event::one_event 0; # for now
169 root 1.1 }
170    
171     =item $result = loop([$timeout])
172    
173     This is the version of C<loop> you should use instead of C<Event::loop>
174     when using this module - it will ensure correct scheduling in the presence
175     of events.
176    
177     =item unloop([$result])
178    
179     Same as Event::unloop (provided here for your convinience only).
180    
181     =cut
182    
183 root 1.40 $Coro::idle = \&Event::one_event; # inefficient
184 root 1.9
185 root 1.1 1;
186    
187 root 1.36 =back
188    
189 root 1.1 =head1 AUTHOR
190    
191 root 1.27 Marc Lehmann <schmorp@schmorp.de>
192 root 1.25 http://home.schmorp.de/
193 root 1.1
194     =cut
195